Circular Dependency Problem

from java 2010/03/26 10:55
Circular Dependency의 해악은 개발을 하다보면 자연스럽게 알게 된다..
회사에서 개발하는 시스템중에 처음에는 그러하지 않았을 것인데, 아키텍처링을 할 수 없는 지금의 조직에서 자연스럽게 Circular Dependency를 걸어버렸다.. 일정이라는 최고의 명제 아래 말이다..
결국, 의존과 버전에 묶여서 뗄레야 뗄루 없는 커플처럼 되어 버린 기존의 시스템은 또다시 거대한 레거시로의 한발한발 다가서고 있다.. 정말로 뗄 수 없을 정도로 말이다..
누군가는 나서서 해결을 해야 겠지만, 누가 하겠는가.. 일정에 맞춰서 들어온 일 처리해야쥐..
결국 시스템의 모습은 직책자들의 마인드와 의지가 만들어 내는 우리의 현실이며, 이 모습은 좋은 개발팀 혹은 좋은 개발실은 아니라는 느낌을 지울 수 없다..

아래 Building속성에서의 Circular dependencies는 Warning이 아니라 Error 상황이 되어야 된다.
그래서, 위의 상황을 미연에 방지를 해야된다.. 단순한, 일정에 맞춰야 되서 Warning이 Default가 되어서는 안될 것이다.. ^^;;




'java' 카테고리의 다른 글

간단한 SOAP 메시지 콜  (0) 2010/05/26
garbage collector  (0) 2010/04/29
Circular Dependency Problem  (0) 2010/03/26
String의 공백은 trim()을 두번 호출해야 된다는 얘기에 대해서..  (0) 2010/03/04
소켓 연결 확인하기..  (0) 2010/03/03

Framework vs Toolkit

from lectures 2010/03/25 10:15
프레임웍과 툴킷의 차이입니다.
아래 내용은 http://kamalmeet.com/?p=24 에서 참고를 하였습니다.
a toolkit is something which will provide you with some tools or methods which will help you achieve your goal.

a framework is something that provides you a way in which the application should be created.


'lectures' 카테고리의 다른 글

uml - association  (0) 2010/04/11
delegation in java  (0) 2010/04/06
Framework vs Toolkit  (1) 2010/03/25
Platform vs. Framework  (1) 2010/03/24
How to Design a Good API & Why it Matters by Joshua Bloch  (0) 2010/01/26
Tag // Framework, toolkit

Platform vs. Framework

from lectures 2010/03/24 14:58
플랫폼과 프레임웍에 대한 비교내용입니다.
wikipedia보다 더 잘 정의가 되어 있는 내용이 있어서 올려봅니다.
아래 내용을 읽어보니, 느낌이 확 오네요.. ^^
출처 정보는 아래와 같습니다. 흠. 복사할때 아래의 정보를 넣어주네요.. 네이버 참 좋다..^^

platform

 

1) In computers, a platform is an underlying computer system on which application programs can run. On personal computers, Windows 2000 and the Mac OS X are examples of two different platforms. On enterprise servers or mainframes, IBM's S/390 is an example of a platform.

A platform consists of an operating system, the computer system's coordinating program, which in turn is built on the instruction set for a processor or microprocessor, the hardware that performs logic operations and manages data movement in the computer. The operating system must be designed to work with the particular processor's set of instructions. As an example, Microsoft's Windows 2000 is built to work with a series of microprocessors from the Intel Corporation that share the same or similar sets of instructions. There are usually other implied parts in any computer platform such as a motherboard and a data bus, but these parts have increasingly become modularized and standardized.

Historically, most application programs have had to be written to run on a particular platform. Each platform provided a different application program interface for different system services. Thus, a PC program would have to be written to run on the Windows 2000 platform and then again to run on the Mac OS X platform. Although these platform differences continue to exist and there will probably always be proprietary differences between them, new open or standards-conforming interfaces now allow many programs to run on different platforms or to interoperate with different platforms through mediating or "broker" programs.

2) A platform is any base of technologies on which other technologies or processes are built.

 

framework

In general, a framework is a real or conceptual structure intended to serve as a support or guide for the building of something that expands the structure into something useful.

In computer systems, a framework is often a layered structure indicating what kind of programs can or should be built and how they would interrelate. Some computer system frameworks also include actual programs, specify programming interfaces, or offer programming tools for using the frameworks. A framework may be for a set of functions within a system and how they interrelate; the layers of an operating system; the layers of an application subsystem; how communication should be standardized at some level of a network; and so forth. A framework is generally more comprehensive than a protocol and more prescriptive than a structure.


eclipse에서 java source 보기

from tools 2010/03/16 16:01
eclipse에서 자바로 개발을 하다보면, 라이브러리나 API대상의 코드를 확인하기 위해서 f3키를 눌려서 확인을 합니다.
특히, java api source를 보기 위해서는 자바 소스를 간단하게 링크만 하면 됩니다.

아래의 이미지처럼, JRE System Library에서 rt.jar의 속성창에서 Java Source Attachment의 Location path에 src의 위치를 확인시켜 주면 소스가 잘 나오네요.. ^^


'tools' 카테고리의 다른 글

json simple library  (0) 2010/05/18
java c/c++, c# 호출방식  (0) 2010/04/29
eclipse에서 java source 보기  (0) 2010/03/16
build.xml refactoring using macrodef tag  (1) 2010/03/15
staruml  (0) 2010/02/08
Tag // Eclipse, java, rt.jar

Enterprise Integration Patterns

from books 2010/03/16 14:03
엔터프라이즈 환경에서 레거시 시스템들과의 통합이 이슈화 되는 시점에서 이것저것 찾아보니, 좋은 책이 있네요..
Enterprise Integration Patterns, Web Service, SOA, ESB등의 개념에 대한 비교도 http://www.enterpriseintegrationpatterns.com/eaipatterns.html 에 잘 설명이 되어 있네요.. 그리고, http://www.enterpriseintegrationpatterns.com/toc.html 에 각 패턴에 대한 간단한 기술이 되어 있어서 대충 감을 잡기에도 좋네요..


'books' 카테고리의 다른 글

24시간 365일 서버/인프라를 지탱하는 기술..  (0) 2010/07/16
Enterprise Integration Patterns  (0) 2010/03/16
낭중에 아래의 형태로 추가를 해야겠습니다.

public boolean write(ArrayList<ConfigValue> list) throws Exception {
                
        for(int i=0; i < list.size(); i++) {
            System.out.println(list.get(i).getService() +" - "+ list.get(i).getKey()+" - "+ list.get(i).getValues().toString());
        }
       
        String fileName = "config-test.xml";
        String empty ="    ";        
       
        try {       
            XMLOutputFactory xmlFactory = XMLOutputFactory.newInstance();
            XMLStreamWriter writer = xmlFactory.createXMLStreamWriter(new java.io.FileWriter(fileName));
       
            writer.writeStartDocument("1.0");
            writer.writeCharacters(System.getProperty("line.separator"));
            writer.writeStartElement("sjava-config");
            writer.writeCharacters(System.getProperty("line.separator"));
           
           
            String serviceName = list.get(0).getService();
           
            ArrayList<String> serviceList = new ArrayList<String>();
            serviceList.add(serviceName);
           
            for(int i=0; i < list.size(); i++) {
                if(!serviceName.equals(list.get(i).getService()) ) {
                    serviceName = list.get(i).getService();
                    serviceList.add(serviceName);
                }
            }
           
            for(int i=0; i < serviceList.size(); i++) {
                writer.writeCharacters(empty);
                writer.writeStartElement("sjava-service");
                writer.writeAttribute("name", serviceList.get(i));
                writer.writeCharacters(System.getProperty("line.separator"));
               
               
                for(int j=0; j < list.size(); j++) {
                    if(serviceList.get(i).equals(list.get(j).getService()) ) {
                        serviceName = list.get(j).getService();
                       
                        writer.writeCharacters(empty + empty);
                        writer.writeStartElement("key");
                        writer.writeAttribute("name", list.get(j).getKey());
                       
                        String tmpValue = "";
                        for(int z =0; z < list.get(j).getValues().length; z++) {
                            tmpValue += list.get(j).getValues()[z];
                            if(z != list.get(j).getValues().length-1)
                                tmpValue +=",";
                        }
                           
                        writer.writeAttribute("value", tmpValue);
                        writer.writeEndElement();
                        writer.writeCharacters(System.getProperty("line.separator"));
                    }
                }
                writer.writeCharacters(empty);
                writer.writeEndElement();
                writer.writeCharacters(System.getProperty("line.separator"));
            }
           
            writer.writeEndElement();
            writer.flush();
            writer.close();
           
        } catch(Exception e) {
            e.printStackTrace();
        }
       
        return true;
    }

위 코드로 아래의 결과를 만들어 낼 수 있다.
<?xml version="1.0"?>
<sjava-config>
    <sjava-service name="sjava-config">
        <key name="watch" value="false"></key>
        <key name="period" value="60"></key>
    </sjava-service>
    <sjava-service name="sjava-logging-server">
        <key name="host" value="111.111.111.111,222.222.222.222"></key>
        <key name="port" value="20003"></key>
    </sjava-service>
</sjava-config>

Tag // java, sjava-config
The ThoughtWorks Anthology 라는 책의 11 챕터의 빌드 아케텍트인 줄리안 심슨님의 내용은, build.xml 즉, ant 파일이 refactoring에 대한 내용입니다.  그 중에서, <macrodef> 태그를 이용한 build.xml 파일의 리펙토링 예제가 나오는데, 유용할것 같아서 개인적으로 사용하고 있는 dist target에 대해서 리펙토링을 적용해 봤습니다.

기존
<!-- distribute compiled binary to dist folder -->
    <target name="dist" depends="compile" description="distribute library">
        <echo>dist target started</echo>
        <jar destfile="${dist.dir}/${project.name}-${project.version}.jar">
            <fileset dir="${build.main.classes}"></fileset>
           
            <manifest id="MANIFEST.MF">
                 <attribute name="Built-By" value="${user.name}"/>
                 <!--attribute name="Class-Path" value="${class-path}" /-->   
             </manifest>
        </jar>
       
        <copy todir="${dist.dir}">
            <fileset dir="${lib.dir}">
                <exclude name="junit*.jar" />
            </fileset>
        </copy>
       
        <!-- compress binary -->
        <zip destfile="${dist.dir}/${project.name}-${project.version}.zip" >
            <fileset dir="${dist.dir}" includes="**" />
        </zip>
        <echo>dist target completed</echo>
    </target>   

리펙토링된 후
    <macrodef name="dist_jar">
        <sequential>
            <jar destfile="${dist.dir}/${project.name}-${project.version}.jar">
                <fileset dir="${build.main.classes}"></fileset>
                <manifest id="MANIFEST.MF">
                    <attribute name="Built-By" value="${user.name}"/>
                    <!--attribute name="Class-Path" value="${class-path}" /-->   
                </manifest>
            </jar>
        </sequential>
    </macrodef>
   
    <macrodef name="dist_copy">
        <sequential>
            <copy todir="${dist.dir}">
                <fileset dir="${lib.dir}">
                    <exclude name="junit*.jar" />
                </fileset>
            </copy>
        </sequential>
    </macrodef>
   
    <macrodef name="dist_zip">
        <sequential>
            <!-- compress binary -->
            <zip destfile="${dist.dir}/${project.name}-${project.version}.zip" >
                <fileset dir="${dist.dir}" includes="**" />
            </zip>       
        </sequential>
    </macrodef>
   
    <!-- distribute compiled binary to dist folder -->
    <target name="dist" depends="compile" description="distribute library">
        <echo>dist target started</echo>
        <dist_jar />
        <dist_copy />
        <dist_zip />
        <echo>dist target completed</echo>
    </target>   

위 예제처럼, 리펙토링된 내용을 살펴보면, <macrodef>태그를 통해서 기능에 대한 내용을 작게 쪼개서 빼고(<macrodef>) , 사용하는 <target>에서는 필요한 각 기능을 호출하는 템플릿 메쏘드(?)처럼 기술하게 됩니다. 어디서 많이 본 느낌인데.. 위는 기능을 작게 나눠서 메쏘드로 뽑는 extract method 리렉토링 기법과 동일하네요.. 역시 대가들에게서 많은 내용을 배우게 되는것 같습니다. ^^


'tools' 카테고리의 다른 글

java c/c++, c# 호출방식  (0) 2010/04/29
eclipse에서 java source 보기  (0) 2010/03/16
build.xml refactoring using macrodef tag  (1) 2010/03/15
staruml  (0) 2010/02/08
FindBugs 사용하기..  (0) 2010/02/02
Tag // Ant, Refactoring

Scalable IO in Java

from data 2010/03/09 17:53
Doug Lea 교수님께서 강의를 위해서 만들어놓은 자료입니다. 어디에서 다운로드를 받았는지 기억이 안나서 업로드 합니다.

PDF 자료를 보시면,  POSA2의 Reactor 패턴을 이용해서 이벤트를 디스패칭하는 내용을 기본으로, 약 3가지의 모델을 제시하고 있고, 그 중에서 Using Multiple Reactors 슬라이드 편이 가장 성능이 좋을거 같습니다.



위와 같은 모습의 서버 프레임웍을 조만간 공개할 예정입니다.
혹시, nio 기반의 소켓서버를 개발하시는 분들에게 도움이 되었으면 하네요.. ^^
sjava-config, sjava-logging 라이브러리가 1.4버전으로 업데이트 되었습니다.
sjava-config(1.4) : http://sjava-config.googlecode.com/files/sjava-config-1.4.zip
sjava-logging(1.4) : http://sjava-logging.googlecode.com/files/sjava-logging-1.4.zip


어느 윗분께서 String의 trim()을 사용하면, 한번더 호출해야 정확하게 trim()이 된다고 말씀을 하셔서.. String 클래스의 trim()메쏘드를 살펴보니 아래와 같이 코딩이 되어 있네요..

    public String trim() {
        int len = count;
        int st = 0;
        int off = offset; /* avoid getfield opcode */
        char[] val = value; /* avoid getfield opcode */
     
        while ((st < len) && (val[off + st] <= ' ')) {
            st++;
        }
       
        while ((st < len) && (val[off + len - 1] <= ' ')) {
            len--;
        }
       
        return ((st > 0) || (len < count)) ? substring(st, len) : this;
    }

위 코드를 살펴보면, char[]의 ' ' <-- 공백을 앞쪽에서는 st를 뒤로 밀고, 뒤쪽에서는 len을 앞쪽으로 땅기면서 substring을 하게 되어 있네요..

위 코드를 보면 분명히 한번만 trim()하면 공백이 날라가네요.. ^^


소켓 연결 확인하기..

from java 2010/03/03 12:19
소켓을 기반으로 풀링을 하는 라이브러리를 개발할 시에 보통 소켓 클래스의 isconnected 라는 상태변수를 통해서 소켓의 연결상태를 확인할 수 있으나, 정확한 정보는 아니죠.. isconnected라는 변수는, 마지막 네트웍 이벤트를 처리한 소켓의 연결 상태이기 때문이죠.. 그래서 확실하게 풀을 관리하기 위해서는 네트웍 이벤트를 발생시켜 보는것이 Java에서는 해결책이라고 봐야 될듯 합니다. 
아래코드는 SocketChannel이 non-block인 상태를 기준으로, read 메쏘드를 호출했을 경우, 리턴값을 보고 상태를 확인하는 코드입니다.

int  readbytes = socketChannel.read(buf);

// 연결이 되어 있음..
if(readbytes == 0)
// 끊어졌네요.
if (readbytes == -1)
// 리시브된 데이타가 있네요..
if(readbytes >0)

소켓 풀링을 관리하는 매니저 클래스가 풀에 들어있는 소켓의 read 이벤트를 주기적으로 호출해보면, socket의 연결상태를 잘 유지할 수 있을 것입니다. ^^