2009년 12월 22일 화요일

GridLayout component의 행, 렬 동적 변환

어떤 이벤트가 발생하면 jbutton들의 행과 열의 형태를 바꿔주는 경우가 필요했다.

예를 들어

1
2
3
4

이런 형태로 배열되있는 버튼이 어떤 이벤트에 의해

1 2
3 4

와 같이 2x2 형태로 배열되는 경우였다.

검색해 보니 GridLayout을 이용하여 속편히 해결 할 수 있었도다,,,, 후후후

public void actionPerformed(ActionEvent e) {

if(e.getSource() == b1) {
System.out.println("click");
gl.setColumns(2);
gl.layoutContainer(p3);

}
}

이런식의 소스임.

http://java.sun.com/docs/books/tutorial/uiswing/layout/grid.html
이곳에 예제 소스가,,,,


2009년 11월 9일 월요일

TPTP 프로파일링 Part 1, TPTP 설치 및 메모리 누수 찾기 Java


출처 : http://javacan.tistory.com/115

TPTP를 이클립스에 설치하는 방법과 TPTP를 이용하여 메모리 누수 코드를 찾는 방법에 대해서 살펴본다.

TPTP 설치하기

메모리 누수를 찾는 것은 쉽지 않은데 그 이유는 메모리가 부족한 현상이 어플리케이션을 실행하자 마자 곧 바로 나타나는 것이 아니라 짧게는 1-2시간, 길게는 1주일 후에나 발생하기 때문이다. 예를 들어, 웹 어플리케이션을 구동하면 대략 48시간 정도 후에 시스템에서 OutOfMemoryError 와 같은 치명적 에러가 발생하면서 어플리케이션이 죽는 경우가 있을 것이다. 또한, 메모리가 부족하여 시스템이 죽는 걸 알게 되어도 어떤 코드 때문에 메모리 누수 현상이 발생하는 지 찾는 것 또한 쉽지 않다.

메모리 누수 현상이 발생할 경우 이를 해결하는 가장 좋은 방법은 어플리케이션을 프로파일링 하여 메모리 누수가 될 만한 코드를 찾는 것이다. 프로파일링을 통해서 메모리 누수가 발생하는 코드를 찾을 수 있도록 도와주는 다양한 툴이 존재하는데, 본 글에서는 TPTP가 제공하는 프로파일링 기능을 사용하여 메모리 누수가 예상되는 코드를 찾아내는 방법에 대해서 살펴볼 것이다.

TPTP 설치하기

TPTP는 이클립스 Test & Performance Tool Platform 프로젝트의 약자로서, 이클립스에서 오픈 소스로 진행중인 테스트 및 성능 관련 툴을 위한 플랫폼이다. TPTP는 모니터링, 테스트 자동화, 프로파일링 등 어플리케이션의 문제점을 찾고 해결하는 데 도움이 되는 기능을 제공하고 있다. TPTP는 이클립스 플러그인으로 제공되며, 설치 과정은 아래와 같다.

  1. 이클립스 3.2 설치: http://www.eclipse.org/downloads/
  2. EMF 2.2.1 SDK 버전(EMF, SDO, XSD가 함께 포함된 배포판)을 다운로드 하여 이클립스 폴더에 설치:http://www.eclipse.org/emf/downloads/
  3. UML2 2.0.1 SDK 버전을 다운로드하여 이클립스에 설치:http://download.eclipse.org/tools/uml2/scripts/downloads.php
  4. TPTP 4.2.0.x All Runtime 버전을 다운로드 하여 이클립스에 설치: http://www.eclipse.org/tptp/
EMF, UML2, TPTP 등은 모두 플러그인 형태로 제공되기 때문에, 압축을 풀면 plugins 폴더와 features 폴더가 생성된다. 이 두 폴더를 이클립스 디렉토리에 그대로 복사한 뒤 이클립스를 재실행하기만 하면 모든 설치가 완료된다. 이클립스를 실행한뒤, 'Run' 메뉴를 클릭하면, 아래 그림과 같이 프로파일과 관련된 메뉴가 추가된 것을 확인할 수 있다.

 
위에서 설명한 EMF, SDO, XSD, UML2의 버전은 이클립스 3.2에서 올바르게 동작하는 것으로 이클립스 3.1을 사용할 경우 그에 알맞은 버전을 설치해야 TPTP를 실행할 수 있으니 주의하기 바란다.

메모리 누수를 찾는 과정

자바는 개발자가 별도로 메모리 관리를 하지 않아도 가비지 콜렉터를 통해서 사용되지 않는 객체를 메모리에서 제거해준다. 가비지 콜렉터가 메모리 관리를 수행하는 알고리즘이 단순하진 않지만, 기본적으로 더 이상 참조되지 않는 객체를 가비지로 인식하여 해당 객체를 메모리에서 제거하게 된다. 예를 들어, 아래의 코드를 살펴보자.

    Human h = new Hunam(); // 새로운 Human 객체 생성
    ....
    h = null; // 더 이상 Human 객체를 참조하지 않음

위 코드에서 새로 생성한 Human 객체를 h 가 참조하도록 했는데, 어떤 처리를 수행한 후 h 에 null을 할당하였다. 이렇게 되면 생성된 Human 객체는 더 이상 참조되지 않으며, 가비지 콜렉터의 대상이 된다. 객체가 더 이상 참조되지 않는다고 해서 곧바로 메모리에서 제거되는 것은 아니며, 메모리가 부족하거나 인위적으로 가비지 콜렉터를 실행했을 때 비로서 참조되지 않는 객체가 메모리에서 제거된다.

하지만, 개발자의 실수로 더 이상 사용되지 않는 객체를 어디선가 참조하게 되면, 그 객체는 가비지 콜렉터의 대상이 되지 않으며 따라서 지속해서 메모리에 남아 있게 된다. 이런 객체가 많아질수록 메모리는 불필요한 객체로 공간을 낭비하게 되며, 결국 새로운 객체를 생성해서 저장할 메모리 공간이 부족한 상태가 발생하게 된다.

메모리 누수를 발견하는 과정

메모리 누수가 발생하는 이유는 가비지 콜렉터에 의해 메모리에서 제거되어야 할 객체가 계속해서 누군가에 의해 참조되고 있기 때문일 것이다. 따라서, 어떤 객체가 메모리 누수를 일으키는 지 알아내기 위해서는 특정 시점에 메모리에 저장된 객체들의 상태를 알아내는 것이 중요하다. 즉, 현재 어떤 클래스의 객체가 몇개 만들어졌고, 그 중에 몇개가 가비지 콜렉터에 의해 제거되었고, 또, 객체들 사이의 참조 관계는 어떻다라는 것을 알아야 하는 것이다.

대부분의 프로파일링 툴은 특정 시점의 메모리 상태를 알아낼 수 있는 기능을 제공하고 있으며, TPTP가 제공하는 프로파일링 툴 역시 이 기능을 제공하고 있다. 이 기능을 사용하면 특정 시점의 메모리 스냅샵을 생성할 수 있는데, 툴 마다 다르지만 TPTP의 경우는 다음과 같은 메모리 스냅샵을 제공한다.


위 그림을 보면 현재까지 생성된 객체의 개수와 살아있는(active) 객체, 그리고 제거된(collected) 객체의 수 뿐만 아니라 바이트 단위로 현재 사용중인 메모리 사용량까지 표시되어 있다. TPTP 이외의 프로파일링 툴 역시 이와 비슷한 정보를 제공하며, 아래와 같은 절차에 따라 메모리 누수가 발생하는 객체를 찾을 수 있게 된다.


메모리 누수를 발생시킬거라고 의심되는 코드를 실행하기에 앞서 메모리 스냅샵을 구한다. 그리고 나서, 해당 코드를 실행하고 그 다음에 다시 메모리 스냅샷을 구한다. 만약 GC 되어야 할 객체가 잘못된 코드에 의해 GC 되지 않는다면 스냅샷1에서는 존재하지 않았던 (또는 개수가 매우 적었던) 객체의 수가 스냅샷2에서는 증가되어 있을 것이다. 메모리 스냅샷을 구하기에 앞서 GC를 실행하는 이유는 더 이상 참조되지 않는 객체를 메모리에서 제거함으로써 좀더 정확하게 의심 객체를 찾기 위함이다.

TPTP를 사용한 메모리 누수 찾기

TPTP를 사용할 때에도 앞서 설명한 메모리 스냅샷을 사용해서 메모리 누수를 발생시키는 객체를 찾을 수 있으며, TPTP가 제공하는 추가적인 기능을 사용해서 메모리 누수를 발생시키는 메소드까지도 발견해낼 수 있다. 본 절에서는 TPTP를 사용하여 메모리 누수 코드를 발견하는 과정을 살펴보도록 하겠다.

메모리 누수가 발생하는 예제 어플리케이션

일단 메모리 누수를 일으키는 코드부터 작성해보도록 하자.

    package test.memoryleak.human;
   
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.HashMap;
    import java.util.Map;
   
    public class HumanTest {
       
        private Map<Integer, Human> tempMap;
       
        public  HumanTest() {
            tempMap = new HashMap<Integer, Human>();
        }
       
        public void testHuman(int i) {
            Human human = new Human(i);
            tempMap.put(human.getId(), human);
           
            if (i > 0 && i % 3 != 0) { // 의도적으로 i가 3의 배수일 때 tempMap에서 제거되지 않도록 함
                tempMap.remove(human.getId());
            }
        }
       
        public static void main(String[] args) throws IOException {
            HumanTest test = new HumanTest();
           
            System.out.println("press enter ....");
            BufferedReader br = null;
            br = new BufferedReader(new InputStreamReader(System.in));
            br.readLine();
           
            try {
                for (int i = 1 ; i <= 10000 ; i++) {
                    test.testHuman(i);
                    if (i == 10) {
                        System.out.println(i +" humans processed");
                        System.out.println("press enter ....");
                        br.readLine();
                    }
                    if (i > 0 && i % 5000 == 0) {
                        try {
                            Thread.sleep(2000);
                        } catch(Throwable ex) {}
                        System.out.println(i+" humans processed");
                        br.readLine();
                    }
                }
                System.out.println("completed.");
            } catch(OutOfMemoryError ex) {
                System.out.println("error: "+ex.getMessage());
            }
            System.out.println("press any key....");
            br.readLine();
        }
    }

위 코드에서 testHuman() 메소드는 Human 객체를 생성한 뒤 임시로 tempMap에 저장한다. 그리고 Human 객체가 사용된 뒤에 마지막에 임시로 저장한 tempMap에서 Human 객체를 제거한다. 하지만, 메모리 누수 현상을 설명하기 위해 의도적으로 i의 값이 3의 배수인 경우에는 tempMap에서 Human 객체를 제거하지 않았다. 따라서, tempMap에 저장된 Human 객체는 tempMap이 Human 객체를 참조하고 있으므로, GC의 대상이 되지 않게 되며, 곧 메모리 누수가 발생하게 된다.

프로파일 시작하기

메모리 스냅샷을 구하기 위해서는 자바 어플리케이션을 프로파일이 가능한 상태로 실행해야 한다. 프로파일이 가능하도록 어플리케이션을 수행하는 과정은 다음과 같다.

  1. 'Run' > 'Profile As' > 'Java Application' 을 실행
  2. Monitor 탭을 선택해서 프로파일 할 옵션을 선택
     
    • 'Java Profiling' 옵션을 선택한 뒤, 'Edit Options'을 클릭한 뒤, 아래와 같이 조사할 클래스의 범위 선택

      [Next] 버튼을 클릭한 다음에 아래 그림과 같이 어플리케이션이 구동될 때 자동적으로 프로파일을 시작하도록 설정
    • 'Basic Memory Analysis' 옵션을 선택
    • 'Execution Time Analysis' 옵션 선택한 뒤, 'Edit Options'를 클릭하여 'Show execution flow graphical details'를 선택
조사할 클래스의 범위를 지정해주지 않으면 모든 클래스에 대해서 프로파일링 하게 되는데, 이 경우 프로파일링에 따른 부하 때문에 어플리케이션을 실행하는 데 방해를 줄 수도 있다. 따라서, 분석해야만 하는 클래스에 대해서만 프로파일링 하도록 클래스 범위를 지정해주는 것이 좋다.

설정이 완료되었다면 'Ok' 버튼을 눌러서 프로파일을 시작해보자. 그럼, 아래와 같은 대화창이 뜰 것이다.


이 대화창은 'Profiling and Logging' 퍼스펙티브로 전환할지 묻는 것으로 'Yes' 버튼을 클릭하면 아래 그림과 같이 프로파일링을 위한 퍼스펙티브로 전환된다.


위 화면에서 좌측 영역은 프로파일과 관련된 기능을 제공하며, 우측 영역은 프로파일링 정보를 보여준다. 이제 어플리케이션에서 메모리가 누수되는 지점을 찾을 준비가 완료되었다.

메모리 스냅샵으로부터 메모리 누수되는 객체 추측

메모리 누수가 발생하는 지점을 찾기 위해서는 먼저 어떤 객체가 메모리 누수의 범인인지 찾아내야 한다. 이를 위해서는 앞서 설명했듯이 메모리 스냅샷 정보가 필요하다. 예제 어플리케이션은 testHuman() 메소드를 10,000번 실행하는 데, 처음 10번째 까지 실행한 뒤 엔터키 입력을 기다린다. 콘솔 화면에서 엔터키를 눌러보면 아래 그림과 같이 10번 실행된 뒤 키 입력을 기다릴 것이다.


이 상태에서 메모리 스냅샷을 살펴보자. 메모리 스냅샵을 구하기 전에 GC를 먼저 실행해야 하는데, GC는
 아이콘을 클릭하거나 팝업 메뉴를 통해서 실행할 수 있다. GC를 실행한 뒤, 'Basic Memory Analysis'를 더블 클릭해서 메모리 스냅샷을 구해보자. 아래와 비슷한 메모리 스냅샷 결과가 출력될 것이다.


위 그림을 보면 Human 객체가 총 10개 생성되었고 그 중에 4개가 여전히 메모리에 존재하고, 6개는 GC에 의해 메모리에서 제거되었음을 알 수 있다. 4개의 Human 객체가 메모리 존재한다는 사실을 통해서 Human 객체가 메모리 누수를 일으킬 수 있는 가능성을 확인할 수 있다. 이제 콘솔에서 다시 한번 엔터키를 눌러보자. 그럼, 아래 그림과 같이 메모리 부족 현상이 발생함을 알 수 있다.


메모리 스냅샷을 확인하기 위해 GC를 실행하고, 'Memory Statistics' 화면을 'Refresh' 해보자. 그럼, 아래와 같이 메모리 상태에 변화가 생겼을 것이다.


위 그림을 보면 Human 객체가 904개가 생겼는데 이 중에 302개나 메모리에 존재한다는 것을 알 수 있으며, 이를 통해 Human 객체가 누수되고 있다는 사실을 확신할 수 있게 되었다.

객체 참조 그래프로부터 GC 방해 요소 추측

Human 객체가 메모리 누수의 범인이라는 점을 밝혀냈으므로, 이제 어떤 객체가 Human 객체를 참조하고 있는지를 알아내야 한다. 가비지 콜렉터는 기본적으로 어떤 객체에 의해서도 참조되지 않는 객체에 대해서 메모리 반환을 수행하기 때문에, Human 객체가 메모리에 남아 있다는 것은 곧 Human 객체를 누군가가 참조하고 있다는 뜻이된다.

객체 참조 상태를 확인하기 위해서는 먼저 객체 참조 정보를 수집해야 한다. 아래 그림과 같이 팝업 메뉴 또는 해당 아이콘을 클릭함으로써 현재 상태의 객체 참조 그래프를 구할 수 있다.


객체 참조 정보를 구했다면, 이제 아래와 같이 실행하여 객체 참조 정보를 확인하도록 하자.


객체 참조 정보에서 Human 객체의 참조 정보를 확인하면 아래 그림과 같은 그래프를 확인할 수 있다. 아래 그래프를 보면 Human 객체를 HashMap 객체가 참조하고 있고, 이 HashMap 객체를 HumanTest 가 참조하고 있다는 것을 알 수 있다. 즉, HumanTest 객체의 (HashMap 타입의) tempMap 필드가 Human 객체를 저장하고 있다는 것을 확인할 수 있다.



클래스 인터액션 그래프로부터 누수 예상 메소드 추측

HumanTest 클래스의 tempMap 필드가 Human 객체를 참조하기 때문에 Human 객체가 메모리에서 제거되지 않고 메모리 누수를 일이키고 있다는 것을 알게 되었다. 이쯤 되면 대충 어떤 부분에서 잘못된 코드를 작성했는 지 유추해 낼 수 있다. 하지만, 많은 클래스가 존재하고 참조 문제를 일으키는 범인 클래스가 다양한 곳에서 사용되는 경우가 있다. 이런 경우에는 클래스들 간의 인터액션을 살펴봄으로써 어떤 메소드에서 문제가 있는 지를 찾아낼 수 있다. 아래 그림과 같이 'UML2 Class Interaction' 메뉴를 실행해보자.


그럼, 클래스 사이의 메소드 호출 관계 및 실행 순서를 시퀀스 다이어그램을 통해서 확인할 수 있다. 이 그래프를 살펴보면 아래와 같은 부분을 발견할 수 있을 것이다.


위 그림에서 파란색 박스 부분은 올바르게 실행된 testHuman() 메소드의 경우이다. 파란색 부분은 HashMap의 put과 remove가 호출된 것을 확인할 수 있다. 즉, Human 객체를 생성한 뒤 HashMap에 저장했다가 메소드를 종료하기 전에 HashMap에 제거했다는 것을 유추할 수 있다. 반면에 빨간색 박스 부분은 메소드를 리턴하기 전에 remove 메소드가 호출되지 않는 것을 볼 수 있는데, 이는 HashMap에 저장된 Human 객체가 메소드가 testHuman() 메소드가 리턴되기 전에 HashMap에서 제거되지 않는다는 것을 유추할 수 있다. 즉, TestHuman 클래스의 testHuman() 메소드가 메모리 누수를 발생시키는 코드를 포함하고 있다는 것을 알아낸 것이다.

이제 남은 작업은 메모리 누수를 발생시키는 코드를 찾아서 문제를 제거하는 것만 남았다!!

결론

본 글에서는 TPTP가 제공하는 프로파일링 기능을 사용하여 누수되고 있는 객체를 찾아내고, 해당 객체를 누수 시키는 코드를 찾아나가는 과정을 살펴보았다. 본 글에서 소개한 방식을 통해서 여러분은 메모리 누수를 일으키는 문제의 코드를 비교적 빠르게 찾아낼 수 있게 되었을 것이다. 다음 글에서는 TPTP를 사용하여 어플리케이션의 병목(bottleneck) 부분을 찾는 방법에 대해서 살펴볼 것이며, 이를 통해 어플리케이션의 실행 속도를 향상시키는 방법을 배우게 될 것이다.

관련링크:

* 작성자의 허락없이 본 글을 무단으로 복사 및 유포하는 것을 금합니다. 
Posted by madvirus

2009년 11월 6일 금요일

libcurl 설치


8) libcurl 설치
http://curl.haxx.se/libcurl/ 에서 curl-7.10.2.tar.gz

./configure --disable-ipv6 --with-ssl=/usr/local/ssl (if only ssl was built here)
make
make install (libcurl.so is now in /usr/local/lib)

참고 : curl 은 포트를 열어 정보를 가져오거나 정보를 보내는데 쓰이는 강력한 툴이더군요.
저는 https 사이트의 페이지를 긁어오느라 설치하게 되었습니다. 다른 방법이 없더군요.
post와 get 방식 동시 지원됩니다.
설치참고 : http://curl.haxx.se/libcurl/php/install.html

SSL

SSL(Secure Socket Layer)은 넷스케이프사에서 전자상거래 등의 보안을 위해 개발하였다. 이후 TLS(Transport Layer Security)라는 이름으로 표준화되었다. SSL은 특히 네트워크 레이어의 암호화 방식이기 때문에 HTTP 뿐만 아니라 NNTP, FTP등에도 사용할 수 있는 장점이 있다. 기본적으로 Authentication, Encryption, Integrity를 보장한다.

2009년 11월 5일 목요일

유니코드

유니코드(Unicode)는 전세계의 모든 문자를 컴퓨터에서 일관되게 표현하고 다룰 수 있도록 설계된 산업 표준이다. 유니코드 협회(Unicode Consortium)가 제정하며, 최신판은 2008년 4월에 공개된 유니코드 5.1이다. 이 표준에는 ISO 10646 문자 집합, 문자 인코딩, 문자 정보 데이터베이스, 문자들을 다루기 위한 알고리즘 등을 포함하고 있다.

유니코드의 목적은 현존하는 문자 인코딩 방법들을 모두 유니코드로 교체하려는 것이다. 기존의 인코딩들은 그 규모나 범위 면에서 한정되어 있고, 다국어 환경에서는 서로 호환되지 않는 문제점이 있었다. 유니코드가 다양한 문자 집합들을 통합하는 데 성공하면서 유니코드는 컴퓨터 소프트웨어국제화지역화에 널리 사용되게 되었으며, 비교적 최근의 기술인 XML, 자바, 그리고 최신 운영 체제 등에서도 지원하고 있다.

유니코드에서 한국어 발음을 나타날 때는 예일 로마자 표기법의 변형인 ISO/TR 11941을 사용하고 있다.

ASCII

아스키(ASCII, American Standard Code for Information Interchange, 미국 정보 교환 표준 부호)는 영문 알파벳을 사용하는 대표적인 문자 인코딩이다. 아스키는 컴퓨터와 통신 장비를 비롯한 문자를 사용하는 많은 장치에서 사용되며, 대부분의 문자 인코딩이 아스키에 기초를 두고 있다.

아스키는 1967년에 표준으로 제정되어 1986년에 마지막으로 개정되었다. 아스키는 7비트 인코딩으로, 33개의 출력 불가능한 제어 문자들과 공백을 비롯한 95개의 출력 가능한 문자들로 이루어진다. 제어 문자들은 역사적인 이유로 남아 있으며 대부분은 더 이상 사용되지 않는다. 출력 가능한 문자들은 52개의 영문 알파벳 대소문자와, 10개의 숫자, 32개의 특수 문자, 그리고 하나의 공백 문자로 이루어진다.

아스키가 널리 사용되면서 다양한 아스키 기반의 확장 인코딩들이 등장했으며, 이들을 묶어서 아스키라고 부르기도 한다. 대표적으로 7비트 인코딩을 유지한 ISO/IEC 646과, 원래 아스키 코드 앞에 비트 0을 넣어 8비트 인코딩을 만든 IBM 코드 페이지ISO 8859가 있다. 이 인코딩들은 언어군에 따라 같은 숫자에 서로 다른 문자가 배당된 경우가 많다.

GNU

GNU 프로젝트 (GNU project, 그누 프로젝트)는 리처드 스톨만이 완전한 공개 운영 체제GNU 시스템을 만들기 위한 목적으로 시작했다. 이 프로젝트는 1983년 9월 27일 유즈넷 net.unix-wizard 그룹을 통해 일반에 알려졌다. 스톨만은 첫 선언문에 이은 "GNU 선언문"을 비롯한 여러 글들을 통해서, "초기 전산 공동체에 지배적이었던, 협동 정신을 되돌리자"라고 주장했다.

GNU는 "GNU는 유닉스가 아니다."란 의미를 갖는 영어 문장 "GNU's Not UNIX"의 약자로, 원래의 문장 안에 자신이 이미 들어 있는 재귀 약자이다. 스톨만은 GNU를 그누로 읽자고 제안한다. 유닉스는 이미 널리 쓰이던 독점 소프트웨어 운영 체제로, 유닉스의 아키텍처는 기술적으로 믿을만 한 것으로 증명되어 있어, GNU 시스템은 유닉스와 호환될 수 있도록 만들어졌다. 유닉스 아키텍처는 개별적인 요소들이 따로 따로 작성되는 것을 허용한다. 또, 이미 공개되어 있던 조판 소프트웨어 텍(TeX)이나, X 윈도우도 쓸 수 있는 장점이 있었다.

GNU 프로젝트는 누구나 자유롭게 "실행, 복사, 수정, 배포"할 수 있고, 누구도 그런 권리를 제한하면 안 된다는 사용 허가권(License) 아래 소프트웨어를 배포한다. 카피레프트로 불리는 이런 생각은 GPL(GNU 일반 공중 사용 허가서)에 나타나 있다.

1985년에 스톨만은 GNU 프로젝트를 철학적, 법률적, 금융적으로 지원하기 위해 자선단체자유 소프트웨어 재단(FSF, Free Software Foundation)을 세웠다. 이 재단은 GNU를 개발할 프로그래머들도 고용했다. 그러나, 프로젝트의 대부분은 자원 봉사자들이 개발했으며, 앞으로도 그럴 것이다. GNU가 눈길을 끎에 따라, 이를 주목한 회사들은 GNU 소프트웨어의 개발이나 판매 및 기술 지원을 돕기 시작했다. 이 가운데 가장 두드러지고 성공적인 것은 (현재는 레드햇의 일부인) Cygnus Solutions이다.

1990년까지, GNU 시스템엔 확장 가능한 문서 편집기(이맥스), 뛰어난 최적화 컴파일러(GCC), 그리고 표준 유닉스 배포판의 핵심 라이브러리유틸리티가 있었다. 하지만, 여기엔 주요 구성요소인 커널이 빠져 있었다.

GNU 선언문에 서, 스톨만은 "기본적인 커널은 있지만 유닉스를 흉내내려면 아직 더 많은 기능이 필요하다"라고 했다. 여기서 그가 지칭한 것은 MIT에서 개발하여 자유롭게 배포했고, 유닉스 7번째 판과 호환되는 TRIX라는 원격 작업 호출 커널(remote procedure call kernel)이었다. 1986년 12월, 이 커널을 고치는 작업이 시작됐다. 하지만, 개발자들은 결국 TRIX를 기반으로 새 커널을 만드는 것은 어렵다는 결론을 내렸다. 주된 이유는 TRIX는 "애매하고(잘 안 쓰이고?) 비싼 68000 box"에서만 동작했고, 따라서 그 상자에서 쓰이기 전에 다른 구조로 옮겨야(ported) 했기 때문이다. 1988년 즈음에, 카네기멜론 대학교에 서 개발되던 Mach 통신-전송 커널(Mach message-passing kernel)을 그 대체품으로 고려했지만, 이것은 처음에 이것을 개발한 사람들이 AT&T 소유의 코드를 지우면서 지연되었다. 처음엔, 이 커널은 Alix라고 불렸지만, 나중에 개발자 Michael Bushnell는 HURD라는 이름을 선호하여, Alix란 이름은 하부 구조로 옮겨지고 마침내 완전히 떨어졌다. 결국은, HURD의 개발은 기술적이고 개인적인 충돌로 지지부진해 지고 말았다.

1991년리누스 토르발스는 유닉스 호환의 리눅스 커널을 작성하여 GPL 라이선스 아래에 배포했다. 다른 여러 프로그래머들은 인터넷을 통해 리눅스를 더욱 발전시켰다. 1992년 리눅스는 GNU 시스템과 통합되었고, 이로서 완전한 공개 운영 체제가 탄생되었다. GNU 시스템들 가운데 가장 흔한 것이, "GNU/Linux" 또는 "Linux 배포판"이라고 불리는 바로 이 시스템이다. (2003년 기준으로, 허드(HURD)는 여전히 개발 중이며, 리눅스를 대신하여 허드를 사용한 GNU 시스템을 비공식 실험판으로 사용할 수 있다.)

또한, 비공개 유닉스 시스템에도 GNU의 구성 요소들이 오리지널 유닉스 프로그램을 대신하여 들어 있는 경우도 많다. 이는 GNU 프로젝트를 통해 쓰여진 프로그램들이 질적으로 우수하다는 사실을 증명하는 것이다. 종종, 이런 구성요소들은 "GNU 툴"로 불리기도 한다. 다수의 GNU 프로그램은 마이크로소프트 윈도맥 오에스 텐 등으로 포팅되기도 했다.


http://ko.wikipedia.org/wiki/GNU

2009년 10월 29일 목요일

IDE란?

SDK과 API는 대략 혼용해서 많이 쓰기도 하는데요.... 정확히 구분을 하자면..

 

API(Application Programming Interface)는 운영체제 등 큰 틀에서 지원해 주는 함수의 집합군을 이야기 하구요..

 

SDK(Software Development Kit)는 주로 개발툴에서 지원이 되며 최종 개발자가 사용하기 편한 형태로 재구성한 함수집합군을 이야기 합니니다..

 

아마 Apple와 Google가 개발할때 사용하던 SDK 즉 라이브러리나 소스등을 오픈 하나보네요..

 

Visual C++을 예로 들면, Visual C++에서는 많은 SDK를 지원하는데요... 그 SDK는 API기반으로 사용하기 쉽게 재 작성된것도 많이 있죠.

 

IDE(Integrated Development Environment)는 통합개발 환경이라고 하는데요...

 

코딩을 위한 편집기, 컴파일, 링크, 디버그 등... 실행 모듈 개발에 필요한 기능을 통합적으로 합쳐서 만들어놓은 것을 이야기 합니다..

 

위에 예로든 Visual C++이 대표적인 예가 되겠죠...

(네 님이 알고 계신 MS Visual Studio가 정확한 표현이 되겠군요...)

 

통합개발환경과 반대 되는 말이 개별개발환경이라고 하는데요...

 

혹시 유닉스나 리눅스 써보셨나 모르겠습니다..

 

보통 유닉스 리눅스에서 간단한 프로그램을 코딩할때는..

 

vi Edit로 코딩을 하고... vi Edit에서 저장을 하고... 빠져나가서..(빠져나가거나 터미널 하나 더 열거나..)

 

gcc 혹은 cc 명령으로 별도로 컴파일을 해줘야 되는것을 이야기 합니다....

Scripting Language

스크립트 언어(scripting language)란 컴퓨터 프로그래밍 언어로서 응용 소프트웨어를 제어한다. 스크립트 프로그래밍 언어라고도 한다. 스크립트 언어는 응용프로그램과 독립하여 사용되고 일반적으로 응용프로그램의 언어와 다른 언어로 사용되어 최종사용자가 응용프로그램의 동작을 사용자의 요구에 맞게 수행할 수 있도록 해준다. 스크립트(scripts)는 연극 용어인 스크립트에서 유래되었으며 초창기 스크립트 언어는 배치언어(batch languages) 또는 작업 제어 언어(job control language)라고도 불리었다.

CGI

사용자가 서버에게 웹페이지를 통한 요청이 있었을 때, 그것이 응용프로그램에 의해 처리 될 필요가 있다면 서버가 응용프로그램을 실행시키고 필요한 메시지를 받는다. 이 때 서버와 응용프로그램 사이에 데이터를 주고 받기 위한 표준화된 방법을 CGI라고 한다.

2009년 10월 17일 토요일

Open ID

OpenID 란?

OpenID 는 사용자 중심 identity 를 위한 분산형 공개 표준 기술 입니다.

OpenID 는 웹사이트처럼 하나의 URI (URL 또는 주소)로 누구나 인터넷상에서 자신을 식별하게 해줍니다. URI 는 웹 아키텍쳐의 가장 핵심이기 때문에, 사용자 중심 identity 를 위한 단단한 토대를 제공합니다.

OpenID 기술의 첫번째 부분은 인증(authentication -- URI 의 소유자임을 증명하는것) 입니다. 오늘날 웹사이트들은 로긴하기 위해 사용자이름과 암호를 요구하는데, 사실 많은 사람이 같은 암호를 거의 모든곳에 사용하고 있습니다.  OpenID 인증(see specs)에서는, 당신의 이름은 당신의 URI 주소이고 당신의 암호(또는 다른 인증서)는 당신의 OpenID 제공서버(당신이 직접 운영하거나 제 3 자가 제공하는) 에만 안전하게 보관됩니다.

당신은 하나의 OpenID 로 OpenID 를 지원하는 모든 웹사이트들에 복잡한 가입 절차 없이 로긴할 수 있습니다.

OpenID 를 지원하는 웹사이트(생전 처음 방문하는 사이트라도) 에 로긴하기 위해서는, 단지 당신의 OpenID URI 만 입력하면 됩니다. 그러면 그 웹사이트는 인증을 위해 당신을 당신의 OpenID 제공서버로 보냅니다. 일단 인증되면 OpenID 제공서버는 당신을 인증된 상태로 그 웹사이트로 돌려보내 로그인 시킵니다. OpendID 기술은 Strong Authentication 을 적절히 사용함으로써, 확장된 single-sign-on 과 데이타 공유 수준 확장 등 모든 유형의 트랜젝션에 사용될 수 있습니다.

OpenID 기술은 인증외에도 identity 관련 여러 정보를 공유할 수 있는 수단도 제공합니다. 최근의 OpenID 속성 교환 스펙 (see specs)을 통해서, 사용자는 그들의 identity 제공자를 통해서 어떤 정보(이를 테면 이름, 주소, 전화번호 등) 를 공유할 수 있는지 명확하게 통제할 수 있습니다.

오늘날 OpenID 는 사용자 중심 identity 의 사실상 표준으로 여겨지면서, 수많은 사람들이 온라인 상에서 교류할 수 있게 해줍니다.  I Want My OpenID Bounty 같은 프로그램을 통해, 오픈소스 프로젝트의 개발자들은 그들의 커뮤니티를 활성화 하기 위해서 OpenID 지원을 발빠르게 추가 지원하고 있습니다.

혹시 누가 소유하나?

아무도 이 기술을 소유하지 않습니다. 아무도 이로 부터 직접 돈을 벌려고 하지 않습니다. 우리의 목표는 이 기술의 모든 부분을 최대한 자유롭게 이용할 수 있게 하는 것이므로, 아무나 무료로, 라이센스 없이, 어디에 등록할 필요도 없이 이용할 수 있습니다. 이러한 것은 결국 인터넷 커뮤니티 전체를 위한 것이며 우리는 모두 이 커뮤니티의 일부분입니다.

나도 동참할 수 있을까요?

OpenID 의 현재 상태와 다양한 노력을 파악하는 가장 쉬운 방법은 the mailing lists 를 읽어 보시는 것입니다. 또한 현재 진행중인 Heraldry project 를 보시면 미래의 OpenID 에 대한 참고가 되실 것입니다.

(이 사이트는 OpenID 커뮤니티의 허가를 받아 운영하는 openid.net 의 한글판 입니다.)

 

 

http://www.openid.co.kr/

지오 태깅(geo tagging)

지오 태깅은 컴퓨터 파일에 사용자의 위치정보를 함께 덧붙여 주는 것을 뜻합니다. 주로 사진파일에 주로 사용되는 이 기능은 사용자가 GPS기능을 가진 디지털카메라나 휴대전화로 촬영한 사진의 촬영위치를 사진파일의 교환이미지파일형식(EXIF)에 기록해 줍니다. 따라서 사용자는 나중에 사진을 촬영 장소별로 정렬할 수도 있고, 구글어스와 같은 웹서비스와 연동해 지도상에 사진을 나열할 수도 있습니다.

소셜네트워크서비스(SNS)가 발달하면서 외국계 웹서비스업체는 지도서비스와 사진서비스를 연동해 지도검색시 그 지역에서 찍은 사진을 함께 제공해 새로운 비즈니스 모델을 만드는 움직임도 있습니다.

2009년 9월 28일 월요일

LGCNS, 한국형 아마존 EC2 만들었다

IT서비스 회사인 LGCNS가 한국형 아마존 EC2(Elastic Compute Cloud http://aws.amazon.com/ec2) 플랫폼 구축을 완료했다. 클라우드 컴퓨팅(Cloud Computing)에 대한 검토가 무성한 가운데 대형 클라우드 컴퓨팅 서비스 사례가 국내에서 등장하게 됐다.

아마존 EC2는 서버의 자원들을 손쉽게 활용할 수 있는 것으로 LGCNS 클라우드 컴퓨팅 플랫폼 사용자는 서버의 CPU자원, 메모리 개수, 스토리지 크기 등 필요한 IT자원을 웹 사이트를 통해 요청하면 서버 증설 등 기존에 2주일 넘게 걸리던 처리 과정이 엔지니어의 개입 없이 가상 머신을 통해 실시간으로 IT자원이 생성돼 웹에서 바로 사용할 수 있다.

LGCNS는 40대~50대 가량의 노드를 연결해 이번 인프라를 구축한 것으로 알려졌다.

lg_cnscloudcomputing김종완 LG CNS 인프라서비스부문 부문장은 “그동안 개념 파악이나 파일럿(Pilot) 적용을 위한 검토 단계에 머물러 있는 국내 클라우드 컴퓨팅 시장에서 상용화 서비스의 기반을 마련한 의미있는 일”이라고 이번 구축의 의미를 밝혔다.

그는 또 “클라우드 컴퓨팅 플랫폼을 고도화하면서 실제 업무에 적용하는 사례를 확대해 나감으로써 국내 클라우드 컴퓨팅 시장을 선도해 나갈 계획”이라고 덧붙였다.

LGCNS는 마이크로소프트(Microsoft)의 클라우드 컴퓨팅 핵심 아키텍처와 LG CNS의 가상화(Virtualization)와 자동화 기술을 통합해 클라우드 컴퓨팅 플랫폼을 완료했다고 밝혔다.

이번에 구축한 LGCNS의 클라우드 컴퓨팅 플랫폼은 마이크로소프트의 윈도 서버 2008(Windows Server 2008), 가상화 기능을 제공하는 하이퍼-V (Hyper-V), 시스템 관리와 과금과 밀접하게 연관된 시스템 센터(System Center) 제품군 등 윈도(Windows)계열 서버를 바탕으로 구축됐다.

LGCNS는 국내 서버 시장에서 윈도계열 서버가 가장 폭 넓게 사용하고 있어 이 플랫폼을 선택했다고 밝혔다.

LGCNS는 LG그룹사의 관계 회사들은 물론 향후 외부 이용자들에게도 이 클라우드 인프라를 개방할 계획이다. 이렇게 되면 KT나 LG데이콤 같은 서버 호스팅 사업을 벌이고 있는 기존 사업자들과의 일정 부문 충돌도 예상된다. 호스팅 업체들도 가상 서버 호스팅 상품을 제공하고는 있지만 대부분 젠서버(XenServer)를 리눅스 서버에 탑재해 제공한다.

기존 호스팅 업체들의 가상 서버 호스팅을 받으려면 신청 후 1일~2일 정도 걸리지만 LGCNS는 웹에서 신청한 후 바로 사용할 수 있다. 그만큼 탄탄한 인프라를 갖췄다는 것이 LGCNS의 설명이다.

LGCNS는 정확한 상용화 시점에 대해서는 말을 아끼고 있지만 올해 내 상용 서비스를 선보일 것으로 보인다.

한편, LG CNS의 클라우드 컴퓨팅 플랫폼은 비즈니스 현업 적용 시 다양한 비즈니스 효과가 기대된다.

먼저, 요청한 IT자원 제공 시간의 단축으로, 비즈니스 상황 변화에 빠르게 대응할 수 있으며, 시스템 사용이 증가할 경우 용량이 자동으로 확장되고, 사용량이 줄어들 경우 일부 IT자원을 회수하는 등 탄력적인 시스템 운영으로 IT자원 활용을 극대화할 수 있다.

또한, IT자원 할당 시에 수행되는 반복적인 수작업 절차를 자동화함으로써 인건비를 절감하고, IT자원 운영 최적화로 하드웨어 도입 비용을 절감할 수 있으며, 하드웨어 전력 사용량 감소를 통해 CO₂배출량을 줄임으로써 그린 IT를 실현하는 데에도 기여할 수 있다.

한국마이크로소프트 최기영 전무는 “마이크로소프트의 핵심 기술 기반으로 구축된 클라우드 컴퓨팅 플랫폼의 확산을 위해 LG CNS의 사례를 레퍼런스로 활용하여 공동 영업 및 다양한 마케팅 활동을 적극 펼쳐나갈 계획” 이라고 밝혔다.

[참고] ‘클라우드 컴퓨팅’ 이란?

클라우드 컴퓨팅은 ‘인터넷을 기반으로 다수의 사용자들에게 대규모의 IT자원을 서비스 형태로 제공하는 것’을 말한다.

[참고] ‘플랫폼’ 이란?

플랫폼이란, “소프트웨어가 실행되는 환경”이다. 각 소프트웨어 프로그램은 아무 플랫폼에서나 실행되는 것이 아니고 특정 플랫폼에서만 실행된다.

일반적으로, 운영체제인 O/S는 모두 플랫폼이다. Windows는 윈도우즈 프로그램만을 실행시킬 수 있는 플랫폼이고, 리눅스(Linux)는 리눅스 프로그램만을 실행시킬 수 있는 플랫폼이다.

예를 들어, MS사의 오피스 프로그램은 기본적으로 윈도우즈 운영체제에서 구동되도록 만들어졌다. 즉, MS 오피스는 윈도우즈 플랫폼 상에서 실행한다고 말할 수 있다.

[참고] ‘가상화’ 란?
가상화(假像化, virtualization)는  ”물리적인 컴퓨터 리소스의 특징을 다른 시스템, 응용 프로그램, 최종 사용자들이 리소스와 상호 작용하는 방식으로부터 감추는 기술”로 정의할 수 있다.

이는 물리적인 여러 개의 리소스를 하나로 합치기도 하고, 하나의 리소스를 여러 개로 쪼개는 등 유연한 자원 활용을 통해 사용자로 하여금 비용절감을 가능케 하는 기술을 말한다.

[참고] 클라우드 컴퓨팅 플랫폼의 사례

대표적인 해외사례로 미국 아마존(Amazon)의 EC2(Elastic Cloud Compute), 구글의 앱 엔진(App Engine), 마이크로소프트의 윈도 애저(Azure)를 들 수 있다.

이들 클라우드 컴퓨팅 플랫폼에서는 하드웨어가 필요할 때 새로운 서버를 웹 상의 화면에서 요청하면 된다. 요청한 후 10분도 채 되지 않아 사용 준비가 완료되며, 원하는 작업이 끝난 이후, 사용 종료 됐음을 알리는 순간 모든 자원은 다시 클라우드로 되돌아 간다.

[참고] 클라우드 컴퓨팅 시장 규모

시장조사기관 가트너(Gartner)는, 클라우드 컴퓨팅 관련 시장은 오는 2012년 1500억 달러에 이를 것으로 전망하고 있다.

또 다른 조사기관 IDC는 클라우드 컴퓨팅이 2012년까지 전체 IT관련 시장의 25%를 점유할 것으로 예상했으며, 2012년에는 IT관련 비용 중 10%가 클라우드 컴퓨팅에 투입될 것으로 전망하고 있다.

아마존 S3 서비스

'아마존닷컴'하면 떠오르는 이미지는 무엇입니까?
컴퓨터를 조금 만지신다 하시는 분들은 대부분 '책'이나 '음반'같은 것을 판매하는 온라인 쇼핑몰로 생각을 할 것 입니다. 하지만, 책이나 음반 이외에도 이베이처럼 다양한 상품을 팔고 있는 종합 온라인 쇼핑몰이라는 것을 곧 알게 되실 것 입니다. 물론 아마존 매출을 이끌어가는 것은 대부분 음반이나 책이 맞긴합니다.

그런 아마존이 전자지불시스템, 스토리지 서비스, 클라우드 컴퓨팅 등의 서비스를 하신다고 하면 놀라실 분들이 있으실텐데... 아마존의 개발자를 위한 서비스 중에서 S3라고 하는 매력적인 서비스가 있어서 소개드립니다.

아마존이 스토리지 서비스를?

사용자 삽입 이미지

http://aws.amazon.com/s3/에 접속해보세요. S3라고 불리는 아마존의 간단한 스토리지 서비스 제공페이지 입니다. 아마존의 호스팅 서비스가 왜 좋냐면 바로 합리적인 요금과 뛰어난 안전성 덕분입니다.
보통 호스팅 요금은 서버의 일부를 빌리거나, 서버를 전체적으로 빌려서 일단 빌린 만큼 내는 요금이 정해져 있습니다. 그리고 회선료도 정해져 있고요. 그러나 아마존 S3서비스는 사용한 만큼만 비용을 내면 됩니다. 스토리지를 사용한만큼만 요금을 내면되고, 사용하고 있는 스토리지의 용량이 커지면 오히려 단위당 비용은 줄어들도록 되어있습니다. 그리고 회선 요금도, 트래픽이 많으면 많이 내고, 적으면 적게 내는 시스템입니다.

그리고 다년간, 별 문제 없이 세계 최고의 웹사이트를 운영해 온 아마존이니 만큼 그들의 시스템 관리 능력도 매우 안정적일 것 입니다.

트위터, 텀블러 등 해외사이트들은 적극적으로 이용 중...
최근 각광받고 있는 트위터나 텀블러 같은 해외의 사이트들도 아마존의 S3서비스를 이용하고 있습니다. 텍스트 데이터는 본인들이 가지고 있더라도, 이미지나 동영상과 같은 미디어는 아마존에 맡기면 스토리지에 들어가는 비용이 훨씬 절감되겠죠.

사용자 삽입 이미지

새롭게 웹서비스를 시작하는 업체들의 경우 회사의 자본이 넉넉하지 못한 경우가 많습니다. 개발자분들이 덜어 줄 리소스는 개발자분들의 역량에 달려있어 그 분들의 몫이지만, 스토리지 비용이라도 이런식으로 줄인다면 회사 재정적으로도 굉장한 도움이 될 것 같습니다. 갑자기 늘어나는 트래픽으로 서버 비용을 감당하지 못하고 투자도 받기 전에 서비스가 비실대다가 넘어지는 곳도 종종 있더라구요?

제가 영어가 짧은 것도 있고 감이 잘 안오는데,
가격표를 보니 미주지역과 유럽쪽 가격만 명시되어 있네요. 그외 지역에 상주하는 업체에는 서비스가 안되는가 싶습니다. 모쪼록 영어를 잘 하시면 한 번 찔러보시고, 이런 방식의 스토리지 서비스를 이용해서 서버 비용 부담을 줄이는 것도 좋은 방법인 것 같습니다.

Trackback Address >> http://monoeyes.com/trackback/741

네이버 “구글은 무임승차, 화난다”

네이버 “구글은 무임승차, 화난다”
김태정 기자 tjkim@zdnet.co.kr
2009.09.28 / AM 08:56

[지디넷코리아]“한해 수백억원씩 투자해 카페와 블로그, 지식문답 등의 콘텐츠들을 키워왔다. 이를 구글 검색결과로 내놓으라니 화난다”

 


▲ 이준호 NHN 운영책임자.
이준호 NHN 최고운영책임(COO)이 ‘검색황제’ 구글에 대한 불편한 심기를 드러냈다. 구글의 콘텐츠 개방 요구는 ‘무임승차’를 노린 것이라고 날을 세웠다.

 

이 COO는 25일 기자들과 가진 자리서 “구글은 남이 만든 웹사이트 정보를 모아 검색 결과로 제공할 뿐”이라며 “네이버가 힘들게 모아 온 콘텐츠를 무조건 내놓을 이유가 없다”고 밝혔다.

 

실제 구글은 국내 누리꾼들에게 친숙한 카페나 지식문답 콘텐츠가 부족함이 약점으로 꼽혀왔다. 토종 포털들이 구글과의 콘텐츠 연동을 꺼려왔기 때문. 이를 두고 구글은 ‘한국의 폐쇄적 인터넷 문화’라고 불만을 보였었다.

 

이에 대해 토종 포털들은 ‘개방’이란 미명하에 구글에 문을 열 수 없다는 입장을 고수해왔다. 구글의 ‘무임승차’ 요구가 너무하다는 목소리도 점차 커지고 있다. 이 COO는 이 같은 분위기를 다시 강조한 것.

 

이준호 COO는 “카페와 블로그는 우리 누리꾼들이 맞춤형 정보를 공유하는 터전이다”며 “구글은 이를 ‘개방’ 운운하며 그냥 가져가려 한다”고 강조했다.

 

덧붙여 그는 “국내서만큼은 정보의 정교함 측면에서 네이버가 구글보다 월등히 앞서 있다”며 “구글 검색과 네이버를 면밀히 비교해 내린 결론이다”고 말했다.

 

앞으로도 NHN은 구글과의 연동이 아닌 독자적인 검색 노선을 강화할 계획이다. 다음이나 네이트 등이 구글과 연대를 구성한 상황에서도 그렇다. 대신 포털 관리 기술을 소규모 독립사이트에 무상 제공하는 등 개방화 정책에도 노력을 보이겠다는 전략.

 

이미 지난해부터 ‘익스프레스엔진(콘텐츠 관리)’과 ‘큐브리드(DBMS)’, ‘nFORGE(소프트웨어 개발)’ 등 핵심 기술을 무료 공개하며 호응을 얻어왔다.

 

이와 관련 NHN 이람 이사는 “구글 연대가 아니라고 ‘반 개방화’ 기업으로 보는 것은 오류다”며 “우리는 우리만의 개방화 전략들을 갖춰가고 있다”고 설명했다.

2009년 6월 14일 일요일

[DWR] util.js / Basis, Table, List Manipulation

 

2008/07/14 15:15 | Posted by 베스트나
검색을 해보니 DWR util.js에 대해 정리해 놓은 문서들이 없어 대충 정리해 보았습니다.
dwr 홈페이지 영문 메뉴얼로 만으로는 부족한 부분들을 몇개 덧 붙였으며,
크게 기본, 테이블, 리스트에 대한 사용법을 담았습니다.

==================================================================================================

less..

펼쳐두기..

less..

Spring + Ajax with DWR

 


출처 http://whiteship.tistory.com/1251

 

DWR은 Direct Web Remoting의 약어로 자바 객체를 기반으로 자바스크립트 코드를 생성하여, 클라이언트 자바스크립트에서 (생성한 자바스크립트를 사용하여) 서버쪽 자바 객체의 메소드를 호출할 수 있도록 해주는 프레임워크입니다.

수많은 Ajax 프레임워크 중에서 DWR이 Spring와 밀접한 관계가 된 것은 DWR 자체에서 Spring을 지원하는 기능을 구현했기 때문입니다. 따라서 매우 간단하게 Spring와 연동하여 사용할 수 있습니다. 연동한다는 의미를 좀 더 구체적으로 서술하면, Spring Container가 관리하는 bean을 DWR을 사용하여 자바스크립트로 노출시킬 수 있다는 것입니다.

Spring MVC를 사용하든, Spring Web Flow를 사용하든 관계가 없습니다. 어차피 요청은 자바스크립트에서 할 것이고, 이 요청을 처리하는 녀석은 DWR Servlet이지, Spring의 Dispatcher Servlet이 아닙니다. 특정 요청들을 한 곳으로 집중한다는 측면에서 둘은 비슷하지만, View Resolving, Hadler Mapping 까지 관장하는 Spring의 Dispatcher Servlet과는 전혀 다른 일을 합니다. DWR Servlet에 등록되어 있는 자바 객체를 바탕으로 요청을 처리할 자바스크립 코드를 생성하고, 그것으로 처리한 결과를 다시 (클라이언트)웹브라우저에게 돌려주는 역할을 합니다.

사용자 삽입 이미지

클라이언트 자바스크립트에서 특정 요청을 호출하면, 해당 요청을 Dwr Servlet이 받아들이고, Dwr Servlet은 drm.xml에 설정된 정보를 바탕으로 해당 요청을 처리할 자바 객체의 자바스크립트(DWR이 알아서 생성합니다.)를 호출하고 그 결과를 다시 돌려주게 됩니다. 그럼 돌려받은 정보로 비동기식으로 화면에 보여주는 것은 클라이언트쪽에서 알아서 하겠죠.

위 그림에서 Spring이 낑겨들어가는 쪽은 바로 녹색 네모 둘을 연결한 빨간 선입니다. creator는 자바스크립트 생성기를 말하는데, 자바스크립트 코드로 생성할 자바 객체를 지정해 주는데, 이 객체를 Spring Container에 있는 bean을 가져와서 생성할 수 있도록 설정할 수 있습니다.

왜? 스프링 컨테이너가 관리하는 bean으로 설정하려고 할까요? 스프링이 제공하는 DI와 AOP와 같은 기능을 사용할 수 있기 때문입니다. 그런 기능들을 사용하지 못한다면, 자바스크립트로 노출하고 싶어하는 자바 객체 내부에 해당 객체가 필요로 하는 모든 것들이 들어있어야합니다.(new를 많이 사용해서 코딩했겠죠.) 스프링을 사용한다면, 그럴 필요가 없어집니다. 이 말은 더욱 유연하고 유지관리하기 편리한 객체를 자바스크립트로 노출 시킬 수 있다는 뜻입니다.

설명은 이만하고, 다음 글에서 코딩을 해보겠습니다.

Spring + Ajax with DWR (Coding)

 



다음의 순서대로 코딩을 할 수 있습니다.(꼭 이 순서를 지켜야 하는 것은 아닙니다.)
0. POJO로 Ajax (자바스크립트로 노출시킬) 서비스 구현.
1. web.xml에 DWR Servlet 등록하기.
2. dwr.xml 작성하기.
3. 클라이언트 코드 작성하기.
    3-1. 자바스크립트 등록하기.
    3-2. 요청하기.
    3-3. 요청 처리하기.

0. POJO로 Ajax (자바스크립트로 노출시킬) 서비스 구현.
사용자 삽입 이미지
매우 단순하게 구현했으며, MemberService 인터페이스에서는 Member의 이름으로 회원을 검색하여 결과를 리스트 형태로 반환하는 메소드를 가지고 있습니다.

1. web.xml에 DWR Servlet 등록하기.

web.xml에 다음과 같은 코드를 추가합니다.
    <servlet>
        <servlet-name>dwr</servlet-name>
        <servlet-class>
            org.directwebremoting.servlet.DwrServlet
        </servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>true</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>dwr</servlet-name>
        <url-pattern>/dwr/*</url-pattern>
    </servlet-mapping>

/dwr/ 로 시작하는 모든 요청을 DwrServlet이 처리하도록 설정하였습니다.

2. dwr.xml 작성하기.

WEB-INF/ 폴더에 dwr.xml 파일을 다음과 같이 작성합니다.
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"
"http://www.getahead.ltd.uk/dwr/dwr10.dtd">

<dwr>
    <allow>
        <convert converter="bean" match="whiteship.domain.Member" />
        <create creator="new" javascript="MemberService">
            <param name="class"
                value="whiteship.service.MemberServiceImpl" />
        </create>
    </allow>
</dwr>

Member 타입으로 캐스팅 할 수 있도록, converter를 등록해줍니다.
new 생성기를 사용하여, MemberService라는 이름의 자바스크립트를 생성합니다. 이 자바스크립트는 MemberServiceImpl 자바 클래스를 가지고 작성합니다.

=================================================================================
이제 서버쪽에서 설정해야 할 내용은 끝입니다. 이것으로 클라이언트 쪽에서 자바 객체의 메소드를 자바스크립트에서 호출할 수
있습니다. 어떻게 호출하는지 살펴보겠습니다.

3. 클라이언트 코드 작성하기.

3-1. 자바스크립트 등록하기.

View에서 사용할 자바스크립트를 등록합니다.
<script type='text/javascript' src='dwr/engine.js'></script>
<script type='text/javascript' src='dwr/interface/MemberService.js'></script>
<script type='text/javascript' src='dwr/util.js'></script>

맨 아래 한 줄은 옵션입니다. 위의 두 줄은 필수이며, 위의 자바스크립트 파일들이 없다고 걱정하시지 않아도 됩니다. web.xml에서 설정한 dwr/ 경로를 통해 DwrServlet이 알아서 처리할 것입니다.

두 번째 자바스크립트 파일의 이름은 dwr.xml에서 자바 클래스를 자바스크립트로 변환할 때 사용하기로 한 이름으로 설정해주시면 됩니다.

3-2. 요청하기.

폼에서 다음과 같은 input 엘리먼트가 있고, 해당 엘리먼트에서 자바스크립트를 호출합니다.
<form name="memberForm">
    <input type="text" name="name" maxlength="10" onkeyup="inputChanged();" />
</form>

function inputChanged() {
    var name = document.memberForm.name.value;
    if(name.length > 1) {
        MemberService.get(name, updateTable);
    } else {
        DWRUtil.removeAllRows("memberTable");
    }
}


3-3. 요청 처리하기.

위의 자바스크립트에서 updateTable이 바로 요청의 결과를 처리할 자바스크립트 입니다. 다음과 같이 작성합니다.

function updateTable(results) {
    DWRUtil.removeAllRows("memberTable");
    DWRUtil.addRows("memberTable", results, cellFuncs);
}

var cellFuncs = [
    function(data) { return data.name; },
    function(data) { return data.email; }
];

요청의 결과를 가져와서 테이블을 채워줄 때 해당 데이터에서 어떤 필드로 테이블을 채워야 하는지 정의하기 위해 cellFuncs 라는 구조체(?)를 정의해 주었습니다.

참조 : Spring In Action 16장

Spring + Ajax with DWR (Revolution)

 



이전 글의 예제 코드는 DWR을 그대로 사용했을 뿐, Spring은 사용하지 않았습니다. 다시말하면, Spring Container로 부터 bean을 가져온 것이 아니라, new라는 생성기를 사용하여 자바스크립트를 생성했습니다.

스프링 컨테이너가 관리하는 bean으로 자바스크립트를 생성하는 방법은 두 가지가 있습니다.
1. spring 생성기 사용하기.
2. 스프링 설정 파일에서 dwr 네임스페이스 사용하기.(스프링 2.0 이상에서 사용가능)

1. spring 생성기 사용하기.

dwr.xml을 다음과 같이 수정합니다.
new 생성기 대신 spring 생성기 사용하도록 수정.
class 송성 대신 beanName이라는 속성에 bean의 이름을 설정합니다.

<dwr>
    <allow>
        <convert converter="bean" match="whiteship.domain.Member" />
        <create creator="spring" javascript="MemberService">
            <param name="beanName" value="memberService" />
        </create>
    </allow>
</dwr>

그리고 Spring 설정 파일에 memberService라는 bean을 등록해야겠죠. 이 전 예제에서는 등록하지 않았었습니다.

    <bean id="memberService" class="whiteship.service.MemberServiceImpl" />

마지막으로 DWR이 스프링의 설정 파일을 알 수 있도록 설정해야 하는데, 기본으로 ContextLoaderListener를 통해 읽어오려고 합니다. 따라서 web.xml에 다음과 같이 설정되어 있다면, dwr.xml에 별도로 설정해 주지 않아도 됩니다.

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/**Context.xml</param-value>
    </context-param>

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>



2. 스프링 설정 파일에서 dwr 네임스페이스 사용하기.

이번에는 dwr.xml 파일 처럼
별도의 DWR 파일을 사용하지 않고, 스프링 설정 파일로만, DWR로 사용할 bean을 지정해 주는 방벙입니다.

먼저, web.xml에서 등록했던 DwrServlet을 DwrSpringServlet으로 변경합니다.(이제 dwr.xml은 삭제해도 됩니다.)
그럼 다음, 스프링 설정 파일에 dwr 네임스페이스를 추가합니다.
마지막으로, 자바스크립트로 노출시킬 bean 내부에 <dwr:remote> 엘리먼트를 사용하여 설정합니다. 그리고 기본 타입이 아닌 데이터를 변환하기 위해 사용했던 convertor를 등록합니다.

    <servlet>
        <servlet-name>dwr</servlet-name>
        <servlet-class>
            org.directwebremoting.spring.DwrSpringServlet
        </servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>true</param-value>
        </init-param>
    </servlet>

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:lang="http://www.springframework.org/schema/lang"
    xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
    xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.0.xsd
http://www.directwebremoting.org/schema/spring-dwr http://www.directwebremoting.org/schema/spring-dwr-2.0.xsd"
    default-autowire="byName">

    <bean id="memberService" class="whiteship.service.MemberServiceImpl">
        <dwr:remote javascript="MemberService" />
    </bean>

    <dwr:configuration>
        <dwr:convert type="bean" class="whiteship.domain.Member" />
    </dwr:configuration>

</beans>


클라이언트 코드는 수정할 것이 없습니다.

이렇게 하면, 스프링의 DI와 AOP를 적용한 자바 객체를 자바스크립트 형태로 변환해주고(DWR이), 이것을 클라이언트 자바스크립트에서 호출할 수 있게 됩니다.