Vector에 대한 소고

이 기사에서는 다른 알고리즘 관련 도서와 마찬가지로 알고리즘(설계)가 중요하다고 말한다. 전적으로 동의하는 바이다. 알고리즘은 중요하다.

하지만, 전산 경력이 6년이 넘어가도록 알고리즘이 문제가 되었던 적은 알고리즘 관련 수업에서 나오는 과제와 소프트웨어 엔지니어링 수업에서 나온 이상한 과제를 할 때 뿐이었다. 그렇게 중요한 것이라면, 경력의 대부분을 차지하는 현장 경험에서는 왜 알고리즘이 중요하는 사실을 몰랐을까? 적어도 알고리즘을 사용하지 않았을리는 없고, 그렇다면 남들이 해서 숨겨 놓은 알고리즘을 나도 모르게 사용한 것이 아닐까 생각된다. 이런 일들이 가장 잘 일어나는 곳은 데이터베이스와 자바 패키지가 아닐까 생각된다. 데이터베이스는 정렬과 Search를 단 몇 단어로 가능하게 만들지만, 정렬과 Search는 알고리즘에서 가장 중요한 분야 중에 하나이며, 아직도 연구가 끝나지 않은 분야이다. 자바에서 제공하는 표준 API중에도 알고리즘을 제공하는 것이 많다.

자바 표준 API 중에서 java.util 패키지는 알고리즘과 항상 단짝이 되어 나오는 자료 구조(Data Structure)의 Implementation들을 제공하는데, 그 중에 하나가 Vector이다. 실제 얘기에 들어가기 전에 몇 가지 재미난 데이터를 살펴보자.

그림1

위 그래프는 VectorTest.java의 실행결과를 보여주고 있다. 아래 데이터는 VectorInd.java의 실행결과를 보여주고 있다.

> java VectorInd 1000000
Insert Time [749] : 11
Insert Time [61480] : 6
Insert Time [122880] : 48
Insert Time [245760] : 70
Insert Time [491520] : 113
Insert Time [983040] : 215
Insert Time [983917] : 18

소스에서도 알 수 있듯이, 그래프는 각 데이터 크기만큼 Vector에 add를 한 것이고, 변화 폭이 큰 것은 입력되는 위치가 Vector의 처음이고, 아래 그래프는 입력되는 위치가 Vector의 마지막이다. 똑같은 데이터를 입력하지만, 실행 속도는 엄청나게 차이가 난다. 이것을 알고리즘에서 사용하는 용어로 표현하면, 전자의 수행속도는 O(n*n), 후자는 O(n)로 표현된다. 루프를 제외하면, 각각 add에 걸리는 시간은 O(n), O(1)이다. 아래 두 그림은 그 차이를 보여준다.

그림2

위의 그림은 마지막에 입력되는 경우를 보여주고, 아래 그림은 첫번째 위치에 입력되는 경우이다. 아래의 경우에는 입력되어 있는 데이터의 수만큼 데이터가 이동해야 한다. 만약, 10번의 입력이 일어나면, 실제로는 10 + 9 + 8 + … + 2 + 1 = 10 * 9 / 2 번의 시간이 걸니는 것이다. 데이터가 커지면 커질수록 치루어야 하는 대가는 급속하게 커진다.

정말 모든 addLast가 일정한 시간이 들어가는지를 보여주는 것이 VectorInd.java이다. 데이터 입력 시간이 3 millisecond 이상 들어가는 경우에 소요된 시간을 프린트한 것이다. 백만번 중에 7번 발생했다. 처음과 마지막 데이터를 제외하면, 데이터가 두 배가 되어질 때 시간이 많이 걸리는 현상이 발생했다. 그 이유를 그림으로 설명하면 다음과 같다.

그림3

사용자에게 보이지는 않지만, Vector는 데이터를 저장하기 위해 Array를 만들었다. 만든 Array의 사이즈는 무한하지 않기 때문에 데이터를 계속 입력하면, 공간이 부족하게 되고, Vector는 이 때 원래 사이즈의 두 배의 크기의 Array를 만들고, 가지고 있던 데이터를 새로운 Array로 이동시킨다. 즉, Array에 데이터가 입력될 때, Array가 부족하면 기존에 저장된 데이터의 크기(Array 사이즈) 만큼의 데이터 이동이 일어나게 된다. 위 자료에서 보듯이, 데이터 사이즈가 두 배에 도달할 때마다 약 2 배 가량의 시간이 더 걸리는 것을 볼 수 있다.

이때가지의 관찰결과에 따르면, Vector의 인덱스가 작은 쪽에는 입력하는 것도, 삭제하는 것도 좋지 못하다. 그만큼의 댓가(실제 데이터 사이즈 - Index만큼의 데이터 이동)를 치루어야 하기 때문이다. 그리고, 데이터가 입력되는데 걸리는 시간을 반드시 일정한 시간이하로 낮추어야 하는 경우에는 일반적인 Vector를 사용할 수 없다.

실제로 Vector는 인덱스 관리가 편리한 Array에 불과한 것을 알 수 있다. 하지만 Array 작업시 문제가 되는 것들은 여전히 Vector에서도 문제가 된다. 그러므로 처음 넣은 데이터를 가장 먼저 지워야 되는 일에는 Vector를 사용하지 않는 것이 좋다. 이 작은 사실 하나가 위 그래프에서 볼 수 있듯이 데이터가 많은 경우, 실제 프로그램의 실행속도에는 엄청난 영향을 미치게 된다.

Note : VectorInd의 작업결과는 리눅스에서 실행한 것이다. 필자의 윈도우에서는 다른 실행결과가 나왔다. 출력되는 데이터의 모든 시간은 10이였다.

[VectorTest.java]

  1. import java.util.Vector;
  2. import java.util.Calendar;
  3.  
  4. public class VectorTest {
  5.  
  6.     public static void main(String[] args) {
  7.  
  8.          Vector target      = new Vector();
  9.          String obj          = new String("Vector Data");
  10.          Calendar   start, end;
  11.          long    interval   = 0;
  12.          long    LIMIT       = 0;
  13.          int      index       = 0;
  14.  
  15.          long    MAX = Long.parseLong(args[0]);
  16.          
  17.          for ( LIMIT = MAX / 10 ; LIMIT <= MAX ; LIMIT = LIMIT + MAX/10 ) {
  18.              start = Calendar.getInstance();
  19.              for ( index=0 ; index < LIMIT ; index++) {
  20.                   target.add(index, obj);
  21.              }
  22.              end    = Calendar.getInstance();
  23.  
  24.              interval = end.getTimeInMillis() - start.getTimeInMillis();
  25.              System.out.println(index + " " + interval);
  26.              target = new Vector();
  27.          }
  28.  
  29.          System.out.println("===========================");
  30.  
  31.          for ( LIMIT = MAX / 10 ; LIMIT <= MAX ; LIMIT = LIMIT + MAX/10 ) {
  32.              start = Calendar.getInstance();
  33.              for ( index=0 ; index < LIMIT ; index++) {
  34.                   target.add(0, obj);
  35.              }
  36.              end    = Calendar.getInstance();
  37.  
  38.              interval = end.getTimeInMillis() - start.getTimeInMillis();
  39.              System.out.println(index + " " + interval);
  40.              target = new Vector();
  41.          }
  42.     }
  43.  
  44.    
  45. }


[VectorInd.java]


  1. import java.util.Vector;
  2. import java.util.Calendar;
  3.  
  4. public class VectorInd {
  5.  
  6.     public static void main(String[] args) {
  7.    
  8.          Vector target = new Vector(30);
  9.          Object obj      = new Object();
  10.  
  11.          Calendar   start, end;
  12.          long         interval = 0;
  13.  
  14.          int LIMIT = Integer.parseInt(args[0]);
  15.  
  16.          for ( int index = 0 ; index <= LIMIT ; index++ ) {
  17.              start = Calendar.getInstance();
  18.              target.add(obj);
  19.              end    = Calendar.getInstance();
  20.              interval = end.getTimeInMillis() - start.getTimeInMillis();
  21.              if ( interval > 3 ) {
  22.                   System.out.println("Insert Time : " + interval);
  23.              }
  24.          }
  25.  
  26.     }
  27. }



저자 : 김대곤
원문 출처 : http://network.hanb.co.kr/view.php?bi_id=964
2007/06/24 11:17 2007/06/24 11:17
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

CLASSPATH에 없는 클래스 로딩

2007/06/18 01:43

서비 JAVA , , ,

java.lang.reflect를 이용하면 우리가 원하는 클래스에 대한 invoke가 가능하다는 것은 알고 있을 것이다.
하지만 classpath에 등록안되어진 클래스들에 대해서는 어떻게 할 것인가?

일일이 사용자에게 클래스 패스를 설정하게 할수만은 없는 일이다.

보통의 엔진들을 보게 되면 install되어진 디렉토리의 위치만을 세팅하도록 하고 있다.
set JAVA_HOME이라던지
set ANT_HOME이라던지..

쉘스크립트에 의하여 그러한 것들을 정의하여 java process를 띄우곤 하는데 그러면
내가 ant.jar등을 등록하지 않았음에도 불구하고 해당 애플리케이션들이 잘 작동하는 이유는 무엇일까?
그것은 바로 ClassLoader에 숨겨져 있다.
아래에서 보여지는 샘플코드는 classpath 프로퍼티에 등록이 되어지지 않은 클래스들에 대한 조작을 할 것이다.

그렇게 함으로서 이 글을 읽는 당신이 만든 애플리케이션이 별다른 클래스로딩 정책 없이도 작동이 될수 있겠다.
그러려면 또한 잘 알아야 하는것이 reflection API이거늘...
이부분에서는 그러한 것을 생략하고 URLClassLoader를 이용하여 디렉토리나 jar파일을 등록하여 가져오는
방법을 설명하도록 하겠다.

ClassLoader클래스는 이미 1.0API부터 존재해왔으면 URLClassLoader는 1.2에 새롭게 추가된 클래스이다.
우리가 사용하는 파일시스템이 URL이란 이름하에 조작이 될 수 있다는 것을 우선 명심하기 바란다.
왜냐면 file:/// 이란 URI를 사용하기 때문이다.

아래에서는 특정한 디렉토리 안의 jar파일에 대한 class loading샘플을 보여준다..

  1. import java.io.*;
  2. import java.net.*;
  3. public class ClassLoading {
  4.   public static void main(String [] args) throws Exception {
  5.     // Create a File object on the root of the directory containing the class file
  6.     File file = new File("D:/_Develop/jmxSamples/customMBean/log4j-1.2.8.jar");
  7.      
  8.     try {
  9.       // Convert File to a URL
  10.       URL url = file.toURL();          // file:/D:/_Develop/jmxSamples/customMBean/log4j-1.2.8.jar
  11.       URL[] urls = new URL[]{ url };
  12.       System.out.println(urls);
  13.        
  14.       // Create a new class loader with the directory
  15.       ClassLoader cl = new URLClassLoader(urls);
  16.       System.out.println(cl);
  17.        
  18.       // Load in the class; Logger.class should be located in
  19.       // the directory file:/D:/_Develop/jmxSamples/customMBean/log4j-1.2.8.jar
  20.       Class cls = cl.loadClass("org.apache.log4j.Logger");
  21.       System.out.println(cls);
  22.      
  23.     } catch (MalformedURLException e) {
  24.       e.printStackTrace();
  25.     } catch (ClassNotFoundException e2) {
  26.       e2.printStackTrace();
  27.     }
  28.    
  29.   }
  30. }

위에서 보는 것처럼 디렉토리를 설정하거나 특정 jar파일을 사용할 수 있도록 작성한다.
특정파일이 가르키지 않으면 해당 디렉토리의 class파일들을 package형태로 참조하도록 할 수 있는데
해당 디렉토리에 대한 클래스 로딩 샘플을 아래와 같다.

  1. import java.io.*;
  2. import java.net.*;
  3. public class ClassLoading {
  4.   public static void main(String [] args) throws Exception {
  5.     // Create a File object on the root of the directory containing the class file
  6.     File file = new File("D:/_CVSDevelop/jca_hello_adapter/build/classes");
  7.      
  8.     try {
  9.       // Convert File to a URL
  10.       URL url = file.toURL();          // file:/D:/_CVSDevelop/jca_hello_adapter/build
  11.       URL[] urls = new URL[]{ url };
  12.       System.out.println(urls);
  13.        
  14.       // Create a new class loader with the directory
  15.       ClassLoader cl = new URLClassLoader(urls);
  16.       System.out.println(cl);
  17.        
  18.       // Load in the class; Test.class should be located in
  19.       // the directory file:/D:/_CVSDevelop/jca_hello_adapter/build/classes/com/bea/jca/test/Test
  20.       Class cls = cl.loadClass("com.bea.jca.test.Test");
  21.       System.out.println(cls);
  22.      
  23.     } catch (MalformedURLException e) {
  24.       e.printStackTrace();
  25.     } catch (ClassNotFoundException e2) {
  26.       e2.printStackTrace();
  27.     }
  28.    
  29.   }
  30. }

위와 같은 경우에는 classpath의 루트로 잡은 디렉토리를 기준의 package형태로 설정되 파일을
로딩하여 사용할수 있도록 한다.

이 이후의 코딩에는 class가 newInstance를 취한 후 method를 invoking해야 하는 과정을 거치게 되는데
한 가지 주의할 점은 해당 클래스를 반드시 reflection API를 이용하여 호출해야 한다는 점이다.

대략 아래의 코드정도를 이용하여 main 메소드등을 호출하는 클래스를 작성할 수 있을 것이다.

  1. public void invokeClass(String name, String[] args)
  2.     throws ClassNotFoundException,
  3.           NoSuchMethodException,
  4. {
  5.     Class c = loadClass(name);
  6.     Method m = c.getMethod("main", new Class[] { args.getClass() });
  7.     m.setAccessible(true);
  8.     int mods = m.getModifiers();
  9.     if (m.getReturnType() != void.class || !Modifier.isStatic(mods) ||
  10.         !Modifier.isPublic(mods)) {
  11.         throw new NoSuchMethodException("main");
  12.     }
  13.     try {
  14.         m.invoke(null, new Object[] { args });
  15.     } catch (IllegalAccessException e) {
  16.         // This should not happen, as we have disabled access checks
  17.     }
  18. }

reflection에 대한 샘플은 몇가지에 대하여 놀새~ 사이트에 이미 올려져 있으므로 참조하기 바란다.
위와 같은 샘플을 이용하게 되면 서버측 프로그램에 대한 작성을 해볼 수 있는 좋은 기회가 아닐까 한다.

원문 출처 : http://ienvyou.egloos.com/?doc=bbs/gnuboard.php&bo_table=sample_code&page=1&wr_id=68


2007/06/18 01:43 2007/06/18 01:43
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

넷빈즈(NetBeans) 실행하기 - Option 둘러보기 v1.0


사용자 삽입 이미지
 
 
넷빈즈에 프로젝트를 생성하고 java소스를 편집하면 처음 모습은 이렇다..
뭔가 좀 불편해 보인다. 라인넘버도 없고 글자체도 뚜렸하지 않아 무슨 글잔지 모르겠고..
 
개발자에 따라선 편리한 수많은 기능보다는 항상 접하고 눈으로 코드를 보게되는
에디터의 폰트하나, 색상하나에 호불호를 결정하는 사람도 꽤 있으리라 생각한다.
( 본인 역시 그렇지 않다곤 못하겠다.. ^^;; )
 
이번 강좌에선 Option 설정을 통해 이런 부분을 본인 취향에 맞게 수정 해 보자.

넷빈즈를 기동하고 메뉴에서 Tools -> Options 를 선택하면 아래와 같은 대화창이 뜬다.
 
사용자 삽입 이미지

항목들 참 많기도 하다...

큰 카테고리별로 보면

Building : Ant 설정 항목이다. 넷빈즈 4.1은 Ant 1.6.* 대를 번들 하고 있으며 이곳에서
              다른 버전의 Ant를 설정 한다. 참고로 Ant 스크립트까지 여기서 설정 하진 않는다.
              구체적인 Ant 스크립트는 프로젝트를 생성 한 후 각 프로젝트 별로 설정 한다.
Collaboration : 넷빈즈 4.1 부터 번들되기 시작한 모듈로 넷빈즈에 채팅 기능이 들어가 있다고
               생각 하면 된다.. 하지만 IDE에 단순 채팅 기능이 들어가 있다면 큰 의미가 없을 것이다.
               Collaboration 은 다른 넷빈즈 개발자와 함께 같은 소스를 공유하고 함께 수정,컴파일,
               실행 해 볼 수 있다.. 자리를 바꿔가며 개발하는 XP가 아닌 자신의 PC에서 원격의
               상대방과 함께 진행하는 XP가 가능하다.
Editing : 말 그대로 IDE에 있는 편집기에 대한 각종 설정을 할 수 있다.
IDE Configuration : IDE메뉴와 메뉴아이콘에 대한 설정이 들어있으며 메뉴의 이동 삭제 추가 등을
                설정 한다.
Source Creation and Managemenrt : 각종 소스 타입에 따른 템플릿과 버전관리 시스템을
                관리한다.  기본적으로 등록되어 있는 템플릿만 100여개 남짓하며, 물론 기존 템플릿을
                수정 하거나 자신만의 템플릿을 등록 하는것도 가능하다.
                버전관리 시스템은 기본적으로 CVS, PVCS, Visual Source Safe 를 사용 할 수 있도록
                준비 되어 있다.
Testing : 넷빈즈에는 JUnit이 번들되어 있어 별다른 설정없이 유닛 테스트가 가능하며
               Update Center ( http://www.yunsobi.com/tt/subby/37 )를 통해
               NetBeans Extention JUnit 이나 Jellytools, Jemmy Module 같은
               3rd-party 테스트 모듈을 추가 할 수 있다.

위 에서 각 옵션 항목에 대해 간략 히 소개 했다.. 이번 강좌에서 저 몹션들을 모두 다루는건
무리일 것이다. 이번 강좌에는 넷빈즈를 처음열고 꼭 수정해야만 한다고 생각되고, 개발자들이
IDE에서 가장 많이 접하는 Editing 항목만 다루려한다.
나머지 부분은 강좌를 진행하면서 필요할 경우 그때그때 언급하기로 하겠다.

사용자 삽입 이미지


Editing - Editor Settings 항목을 펼치면 각 파일 타입에 대한 항목을 볼 수 있다.

사용자 삽입 이미지


오른편의 Global Key Bindings 항목을 연 화면이다.
소스를 편집하는 데 필요한 기능과 그에대한 단축키를 설정 할 수 있다.

사용자 삽입 이미지


파일 타입에 해당하는 Editor 항목을 열면 오른편 메뉴에서 Abbreviations 항목을 설정 할 수 있다.
말그대로 약어를 등록 해둘 수 있다. 위 화면을 예로들자면  
CSS파일 편집시 에디터에  bg 라고 타이핑 하면 background: 로 대치된다.

사용자 삽입 이미지

 
자..  우리가 손봐야할 자바 소스 에티터 항목을 열었다. 참 많이도 설정 가능하다..
하나하나 다 소개 하고 싶지만 항목을 선택하면 아래쪽에 간략한 소개글이 나오니 필요한 부분을
취향에 맞게 고치면 되겠다.
여기서는 글 서두에서 밝힌대로 폰트 설정과 줄번호 항목에 대해서만 짚고 넘어가겠다.
줄번호 항복은  오른편 메뉴에서 위에서 아홉번째 Line Numbers 항목에 있다.
디폴트로 체크 해제된 상태이다. 체크하면 에디터에서 라인 번호가 표시된다.
그 다음, 위에서 네번째 Font & Colors 항목 을 클릭하면 아래와 같은 대화 상자가 뜬다.
사용자 삽입 이미지

여기서 취향에 맞는 폰트와 색상을 지정하면 된다.  기본적으로 Monospaced 12 Plain

폰트를 사용하고 있다. Monospaced 폰트가 마음에 들지 않는 사람이라면 왼편 신택스 항목의
첫번째 Default 항목에서 Font를 수정하면 모든 신택스에 대해 일괄적으로 변경이 적용되며
각 신택스에 대한 고유한 설정은 신택스 항목을 선택하고 따로 변경 해 주면 된다.
위 화면에서 예시한 Java Keyword의 경우 bold의 Monospaced 라 글자를 알아보기 힘들다.
오른편 폰트 에어리어 아래쪽의 Inherit 항목을 체크하면 Default 항목으로 선택되어 있는
Font 항목이 적용 된다.
Background color 나 Foreground color 역시 각각 설정 가능하며 Inherit 항목을 체크 해
Default 값을 적용 할 수도 있다.

사용자 삽입 이미지


Java Keyword의 Font를 Default font인 Monospaced plain 을 inherit 했다.폰트가 깔끔해 졌다.
HTML,JSP,XML 역시 위와 같은 방법으로 원하는 형태로 에디터를 설정 하면 된다.

자.. 여기서 끝이 아니다. 한가지 더 짚고 넘어갈게 있다.
이 상태에서 프로젝트를 생성해서 에디터를  열고 소스를 편집하면 잘 눈 치채지 못하지만
사용하다보면 '어, 이거 왜 이렇게 해놨지?' 하고 생각 하게되는 부분이 있다.

보통 다른 편집기에서 tab 키를 일반 공백문자 4칸 혹은 8칸 크기로 설정해서 사용 할것이다.
넷빈즈의 경우도 다르지않다. 디폴트로 4칸의 공백문자 크기를 갖는데 문제는 에디터에서
tab 키를 누르면 공백문자 크기만큼 커서가 전진 하지만 tab문자로 전진하지 않고
space bar 를 네번 눌러 전진 한것처럼 동작한다.

혼자 개발 할때는 별 문제 될게 없다. 넷빈즈 에디터에서 열면 들여쓰기가 잘 된걸로 표현
될테니까..  하지만 보통은 협업으로 이루어지며, 다른 개발자도 넷빈즈를 사용한다고 볼 순 없다.
넷빈즈에서 에디팅한 소스를 다른 개발자가 다른 편집기에서 열어보면 짜증을 낼거다.
code indent는 잘 맞추어져있는데 탭을쓰면되는 곳에 왜 스페이스로 들여쓰기를 했냐고..
이 부분은 Editing - Indentation Engines 항목을 통해 교정이 가능하다.

사용자 삽입 이미지


사용자 삽입 이미지


Editing - Indentation Engines - Java Indentation Engine 항목을 클릭하여 오른편 Properties 항목을 보자.
첫번째 항목으로 Expand Tabs to Spaces 항목에 체크 되어 있다. 이 체크를 해제하면 비로소
tab 이 여타의 편집기에서 tab 키를 누른것처럼 기록 될 것이다.
항목 맨 아래쪽의 Statement Continuation Indent 는 여러줄에걸친 코드에서 다음줄로넘어간
경우 처음 탭 크기를 설정하는 부분이며
Number of Spaces per Indent 는 우리가 일반적으로 알고있는 tab에대한 space사이즈 설정부분이다.

사용자 삽입 이미지


마지막으로 짚고 넘어갈게 개발하다보면 자바소스를 특별히 인코딩 방식을 주어 개발해야하는 상황이 종종 발생한다.

Editing - Java Sources 에서 오른편 Default Encoding 항목에서 설정 할 수 있지만 특별한 경우가 아니라면 이곳에 인코딩 설정을 하는것은 추천하지 않는다.
지금까지 살펴본 옵션사항은 각각의 프로젝트에 따르게 적용되는부분이 아닌 넷빈즈 전체에 관한
설정이기 때문이다. 특별히 java 소스에 대한 인코딩이 필요한 프로젝트라면 프로젝트 생성 후
각 프로젝트에 대한 컴파일 인코딩옵션을 설정하는( -encoding UTF-8 , 이 방법 또한 이후 강좌에서 언급하겠다. ) 방식을 추천한다.

---------------------------------------------------------------------------

넷빈즈로 코드 한번 끄적여보기까지 많은 과정을 거쳐왔다...
여기까지가 준비 되었다면 프로젝트를 생성하고 코드를 작성 할 기본적인 준비가 되었다고 할 수 있다.
다음번 강좌부터는 본격적으로 코드와 함께 프로젝트 생성을 다루어 볼까 한다.

ps. 개인적인 지식에는 한계가 있기 마련입니다. 제가 잘못 생각하고 있거나 다른점이 있다면
바로바로 알려주세요.

2007/04/27 10:27 2007/04/27 10:27
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

넷빈즈(NetBeans) 실행하기 - ClassPath 설정 v1.0

교육의 목적으로 JAVA 코드를 작성해 보는게 아니라면(그렇다고 해도 역시 마찬가지지만)JAVA 개발에는 JDK외에 많은 외부 라이브러리를 가지고 개발을 진행한다.
외부 라이브러리의 클래스를 사용한 자바소스를 컴파일 하기 위해 환경변수 설정에 classpath 를 등록 하게 되는데..(너무 기본적인 내용이라 굳이 더 이상 언급하지 않겠다.)IDE를 사용 하게 되면 굳이 환경변수를 바꾸거나, 혹은 classpath 를 설정하는 배치 파일을 작성 할 필요가 없다.(심지어 환경변수에 classpath를 등록 할 필요조자 없다.)

이번 강좌에서는 넷빈즈에 외부라이브러리들을 등록하는 방법을 알아보자.
물론 이전 포스트에서 여러버전의 jdk를 등록하는게 가능했던것처럼 동일라이브러리라도
버전별로 혹은, 프로젝트에 필요한 라이브러리 단위등으로 관리 할 수 있음은 당연하다.

넷빈즈는 JDK를 플래폼 매니저가 관리한다면 외부라이브러리는 Library Manager 가 담당한다.
 

넷빈즈 netbeans

 Tool -> Library Manager 매니저를 선택하여 라이브러리 매니저로 이동한다.

넷빈즈 netbeans


  기본적으로 래이아웃, JSTL, JUnit 관련 라이브러리가 등록 되어 있다. 화면 하단의 New Library... 버튼을 클릭하여 라이브러리 등록 창을 연다.
 
 
넷빈즈 netbeans

 
넷빈즈 netbeans

라이브러리 매니저에서 관리할 라이브러리의 대표이름을 적는다.

넷빈즈 netbeans

새로 등록 한 라이브러리 이름을 선택하고 좌측의 classpath탭에서 Add JAR/Folder... 를 선택한다.

넷빈즈 netbeans

앞서 설정한 랑브러리 명칭에 포함해야 하는 jar 혹은 디렉토리를 하나 혹은 복수개를 선택하여 등록한다.

넷빈즈 netbeans

JAKARTA_COMMONS 라는 이름으로  자카르타 커먼스 프로젝트의 라이브러리 10개를 등록 했다.

넷빈즈 netbeans

JDK설정 편( http://www.yunsobi.com/tt/subby/38 )에서 했던것과 마찬가지로 해당 라이브러리에 대한 javadoc들을 등록한다.


넷빈즈 netbeans
 
위에서 설명한  New Library.. 설정 과정을 반복하여 몇개의 라이브러리를 더 등록 했다.
 
 
자.. 이전 강좌와 이번 강좌를 통해 JDK와 외부 라이브러리 등록 방법을 알아보았다.
이렇게 등록 했다고 해서 프로젝트를 생성하면 바로 적용 등록한 jdk와 라이브러리가
바로 적용 되는건 아니다.
 
앞서도 밝혔듯이 동일 jdk 혹은 라이브러리라도 다른버전을 한번에 관리 할 수 있기 때문에
프로젝트를 만들게 되면 어떤 jdk 를 쓸지, 어떤 라이브러리들을 사용할지 선택해 주는 과정을
거쳐야 한다.
( 강좌를 진행 해 나가면서 하나씩 짚고 넘어갈 것이다. )
 
한번에 하나의 프로젝트만 하고 끝낼거라면 굳이 이렇게 번거로운 등록 작업은 필요 없을것이다.
하지만 한번에 둘, 그 이상의 프로젝트를 진행하거나.. 참여한 프로젝트 수가 늘어갈 수록 이런
관리 방식은 IDE 안에서 많은것을 해결해 주는 좋은 솔루션이 될것이다.
 
 
 
ps. 개인적인 지식에는 한계가 있기 마련입니다. 제가 잘못 생각하고 있거나 다른점이 있다면
바로바로 알려주세요.
2007/04/27 10:12 2007/04/27 10:12
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

넷빈즈(Netbeans) 실행하기 - JDK 설정 v1.0

지난 포스트에서 모듈 업데이트 방법을 알아보았다..
이번에는 JAVA 개발하는데 꼭 필요한 JDK설정을 알아보자.
넷빈즈는 JDK설정을 Java Platform Manager 를 통하여 수행하고 있으며,
복수의 JDK 를 등록 해두고 프로젝트, 혹은 필요할 때 마다 JDK를 교체하며
소스를 빌드 할 수 있다.

netbeans 넷빈즈

netbeans 넷빈즈
 
처음 실행 화면에서 메뉴바의 Tools -> Java Platform Manager 를 선택한다.

netbeans 넷빈즈


그럼, 위와 같은 플래폼 매니저 창이 뜨며 처음 넷빈즈를 설치 할 때 선택 했던 JDK가 선택되어 있으며, 자바 클래스를 컴파일 하는데 기본적으로 필요한 rt.jar등이 기본적으로 설정되어 있다.
다른 버전의 JDK, 혹은, 다른 벤더의 JDK를 등록 하기 위해서는 아래쪽의 Add Platform.. 버튼을 클릭한다.

netbeans 넷빈즈

플래폼 폴더 선택창이 뜨는데.. JDK가 존재 하는 폴더라면 일반 폴더와는 다른 아이콘으로 표시되어 쉽게 구분 할 수 있도록 되어 있다.

netbeans 넷빈즈

플래폼 선택창에서 JDK디렉토리를 선택 한 후 'next' 버튼을 누르면 플래폼 명칭( 일종의 앨리어스 ) 을 적어주고 finish 버튼을 클릭한다.

netbeans 넷빈즈

새로운 JDK가 추가 되었다. 처음과 마찬가지로 기본적인 라이브러리등은 자동으로 세팅 된다.

실제 개발을 하게 될경우 자주 사용한는 클래스와 메소드는 외우고 있기 때문에 상관없지만 간간히
사용하는 클래스나 상속관계등을 살펴볼 필요가 있을경우 API를 참조 하게 된다.
여타의 IDE와 마찬가지로 넷빈즈 역시 javadoc을 설정해 두면 Code Completion 과 함께
API도 보여 주게 된다.

netbeans 넷빈즈

플래폼 매니저에서 오른쪽 탭메뉴에서 Javadoc 을선택 한다.

netbeans 넷빈즈

netbeans 넷빈즈


 해당 JDK버전에 맞는 API폴더를 선택하여 등록 해 두면 개발시 아래와 같이 코드 컴플리션과함께
해당 매소드에 대한 API를 보여준다.

netbeans 넷빈즈
 

이상으로 넷빈즈에 여러버전의 JDK를 등록 해 두는 방법을 알아보았다.
물론 javadoc 을 등록 하지 않는다고 해서 개발을 못하거나 코드컴플리션 기능이 안되는건 아니다.
객체변수에 쩜(.) 찍으면 나오는 코드 컴필리션은 소스, 혹은 class파일 자체를 파싱해서 보여주기
때문에 자바독의 등록 여부와는 상관없다.
단지 개발자라면 API는 항상 곁에 끼고 있어야하는 문서이므로 이왕이면 등록 해두고 자주자주
봐가며 익혀가는게 좋지 않을까 생각 한다.

교육의 목적으로 JAVA 코드를 작성해 보는게 아니라면(그렇다고 해도 역시 마찬가지지만)
JAVA 개발에는 JDK외에 많은 외부 라이브러리를 가지고 개발을 진행한다.
외부 라이브러리의 클래스를 사용한 자바소스를 컴파일 하기 위해 환경변수 설정에
classpath 를 등록 하게 되는데..(너무 기본적인 내용이라 굳이 더 이상 언급하지 않겠다.)
IDE를 사용 하게 되면 굳이 환경변수를 바꾸거나, 혹은 classpath 를 설정하는 배치 파일을
작성 할 필요가 없다.(심지어 환경변수에 classpath를 등록 할 필요조자 없다.)

이번 강좌에서는 넷빈즈에 외부라이브러리들을 등록하는 방법을 알아보자.
물론 이전 포스트에서 여러버전의 jdk를 등록하는게 가능했던것처럼 동일라이브러리라도
버전별로 혹은, 프로젝트에 필요한 라이브러리 단위등으로 관리 할 수 있음은 당연하다.

넷빈즈는 JDK를 플래폼 매니저가 관리한다면 외부라이브러리는 Library Manager 가 담당한다.
 

netbeans 넷빈즈


 Tool -> Library Manager 매니저를 선택하여 라이브러리 매니저로 이동한다.

netbeans 넷빈즈


  기본적으로 래이아웃, JSTL, JUnit 관련 라이브러리가 등록 되어 있다.
화면 하단의 New Library... 버튼을 클릭하여 라이브러리 등록 창을 연다.

 
netbeans 넷빈즈


 

netbeans 넷빈즈

라이브러리 매니저에서 관리할 라이브러리의 대표이름을 적는다.
 

netbeans 넷빈즈

새로 등록 한 라이브러리 이름을 선택하고 좌측의 classpath탭에서
Add JAR/Folder... 를 선택한다.
 

netbeans 넷빈즈

앞서 설정한 라이브러리 명칭에 포함해야 하는 jar 혹은 디렉토리를 하나 혹은 복수개를 선택하여 등록한다.
 

netbeans 넷빈즈

JAKARTA_COMMONS 라는 이름으로  자카르타 커먼스 프로젝트의 라이브러리 10개를 등록 했다.
 

netbeans 넷빈즈


JDK설정 편( http://blog.naver.com/tb/cucmee/70005189784 )에서 했던것과 마찬가지로 해당 라이브러리에 대한 javadoc들을 등록한다.

netbeans 넷빈즈
 
위에서 설명한  New Library.. 설정 과정을 반복하여 몇개의 라이브러리를 더 등록 했다.

자.. 이전 강좌와 이번 강좌를 통해 JDK와 외부 라이브러리 등록 방법을 알아보았다.
이렇게 등록 했다고 해서 프로젝트를 생성하면 바로 적용 등록한 jdk와 라이브러리가
바로 적용 되는건 아니다.
 
앞서도 밝혔듯이 동일 jdk 혹은 라이브러리라도 다른버전을 한번에 관리 할 수 있기 때문에
프로젝트를 만들게 되면 어떤 jdk 를 쓸지, 어떤 라이브러리들을 사용할지 선택해 주는 과정을
거쳐야 한다.
( 강좌를 진행 해 나가면서 하나씩 짚고 넘어갈 것이다. )
한번에 하나의 프로젝트만 하고 끝낼거라면 굳이 이렇게 번거로운 등록 작업은 필요 없을것이다.
하지만 한번에 둘, 그 이상의 프로젝트를 진행하거나.. 참여한 프로젝트 수가 늘어갈 수록 이런
관리 방식은 IDE 안에서 많은것을 해결해 주는 좋은 솔루션이 될것이다.
 
ps. 개인적인 지식에는 한계가 있기 마련입니다. 제가 잘못 생각하고 있거나 다른점이 있다면
바로바로 알려주세요.
2007/04/13 20:38 2007/04/13 20:38
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

Yahoo Buzz Game 에서 자바 IDE 부문에서 넷빈즈가 1위네요..

야후 리서치에 재미있는 조사 결과가 있어서 포스팅 합니다.
불과 일이년전만 해도 자바 개발툴계에 '넷빈즈'라 그러면
'응, 그런 툴도 있지' 수준이었는데 어느새 이클립스 등 여타의 툴과 같은(혹은 이상의)
관심을 받고 있네요.
백번 양보해서 아래 조사결과가 무척 부정확 하다고 해도 여타의 IDE를 따돌리고
이클립스와 어깨를 견줄 IDE로 성장했다는 사실은 변함 없어 보입니다.
넷빈즈 유저로 기쁜일이군요..


        NETBEANS (16.72)
        ECLIPSE (11.58)
        EMACS (9.99)
        JBUILDER (9.62)
        JDEVELOPER (6.66)
        IDEA (5.31)
        WEBLOGIC (4.63)


원문은
http://buzz.research.yahoo.com/bk/market/market.html?_mid=55312

을 보시면 됩니다.
2007/03/26 15:24 2007/03/26 15:24
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다
  1. Blog Icon
    궁금이

    혹시 시중에 넷빈즈 관련 서적이 있나여??

  2. 원서로 두권정도 출간된 적이 있는데요..
    그게 다 넷빈즈 3.x대 서적이라 지금은 거의 도움이 안될겁니다.
    지금 나와있는 서적은 저도 본적이 없구요..
    지금은 netbeans.org에서 정보를 얻으시는게 가장 빠른길인듯 합니다.

Web Services (JAX-WS) in Java EE 5

Java API for XML Web Services (JAX-WS) 2.0, JSR 224, is an important part of the Java EE 5 platform. A follow-on release of Java API for XML-based RPC 1.1(JAX-RPC), JAX-WS simplifies the task of developing web services using Java technology. It addresses some of the issues in JAX-RPC 1.1 by providing support for multiple protocols such as SOAP 1.1, SOAP 1.2, XML, and by providing a facility for supporting additional protocols along with HTTP. JAX-WS uses JAXB 2.0 for data binding and supports customizations to control generated service endpoint interfaces. With its support for annotations, JAX-WS simplifies web service development and reduces the size of runtime JAR files.

This document takes you through the basics of using the IDE to develop a JAX-WS web service and to consume it in three different clients—either a Java class in a Java SE application, or a servlet or JSP page in a web application. The three clients that you create in this document are separate applications, all consuming the same web service.

Expected duration: 25 minutes

Software Needed for the Tutorial

Before you begin, you need to install the following software on your computer:

  • NetBeans IDE 5.5 (download).
  • Java Standard Development Kit (JDK) version 5.0 or version 6.0 (download).
  • Sun Java System Application Server 9.0 (if not bundled with your NetBeans IDE installation, download and install it separately).

Tutorial Exercises

Installing and Configuring the Tutorial Environment

If you have not registered an instance of the Sun Java System Application Server 9.0, you must do so before you can begin developing Java EE 5 applications:

  1. Choose Tools > Server Manager from the main window.
  2. Click Add Server. Select Sun Java System Application Server and give a name to the instance. Then click Next.
  3. Specify the server information, the location of the local instance of the application server, and the domain to which you want to deploy.
  4. Click Finish.

Note: If you want to deploy to the Tomcat Web Server, you can do so, except that, since it only has a web container, you should create a web application, not an EJB module, in the next section. JAX-WS web services, unlike JSR-109 web services, can deploy successfully to the Tomcat web container.

Creating a Web Service

The goal of this exercise is to create a project appropriate to the deployment container that you decide to use. Once you have a project, you will create a web service in it.

Choosing a Container

You can either deploy your web service in a web container or in an EJB container. This depends on implementation choices. For example, if you plan to deploy to the Tomcat Web Server, which only has a web container, you should choose to create a web application, and not an EJB module.

  1. Choose File > New Project (Ctrl-Shift-N). Select Web Application from the Web category or EJB Module from the Enterprise category.
  2. Name the project CalculatorWSApplication.
  3. Depending on the deployment server that you want to use, do the following:
    • For the Sun Java System Application Server, set the J2EE Version to Java EE 5.
    • For the Tomcat Web Server, unselect the Set Source Level to 1.4 checkbox.
  4. Click Finish.

Creating a Web Service from a Java Class

  1. Right-click the CalculatorWSApplication node and choose New > Web Service.
  2. Name the web service CalculatorWS, type org.me.calculator in Package, and click Finish.

    The Projects window displays the new web service. For example, for web applications the Projects window now looks as follows:

    Projects window displaying the web service

    The IDE automatically creates the deployment descriptors required for the server, if any. For the Sun Java System Application Server, no deployment descriptor is needed. For web services deployed to the Tomcat Web Server, sun-jaxws.xml and a WSServlet item in web.xml are added.

Summary

In this exercise, you created a NetBeans project and set up the web service.

Coding the Web Service

The goal of this exercise is to do something meaningful with the files and code that the IDE has generated for you. You will add an operation that will add two numbers received from a client.

Adding Business Logic to the Web Service

  1. Expand the Web Services node and double-click the CalculatorWS node. The web service opens in the Source Editor. Note that an operation exists in the code already. It is commented out. Here, we create a new operation from scratch. Another way of creating the operation would be to remove the lines that comment out the code.
  2. Right-click within the body of the class, either above or below the code that is commented out, and choose Web Service > Add Operation.
  3. In the upper part of the Add Operation dialog box, type add in Name and choose int from the Return Type drop-down list.
  4. In the lower part of the Add Operation dialog box, click Add and create a parameter of type int named i. Click OK.
  5. Click Add again and create a parameter of type int called j.
  6. Click OK at the bottom of the Add Operation dialog box. Notice that a skeleton for the add method has been added to the Source Editor:
        
    1. @WebMethod
    2.     public int add(@WebParam(name = "i") int i, @WebParam(name = "j") int j) {
    3.         // TODO implement operation
    4.         return 0;
    5.     }

  7. Change the add method to the following (changes are in bold):
       
    1. @WebMethod
    2.     public int add(@WebParam(name = "i") int i, @WebParam(name = "j") int j) {
    3.         int k = i + j;
    4.         return k;
    5.     }


Summary

In this exercise, you added code to the web service.

Deploying and Testing the Web Service

When you deploy a web service to a web container, the IDE lets you test the web service to see if it functions as you expect. The Tester application, provided by the Sun Java System Application Server, is integrated into the IDE for this purpose. For the Tomcat Web Server, there is a similar tool. However, while the Sun Java System Application Server's Tester page lets you enter values and test them, the Tomcat Web Server does not. In the latter case, you can only see that the web service is deployed, you cannot test the values. No facility for testing whether an EJB module is deployed successfully is currently available.

To test successful deployment to a web container:

  1. Right-click the project node, choose Properties, and click Run. Depending on the deployment server that you want to use, do the following:
    • For the Sun Java System Application Server, type /CalculatorWSService?Tester in the Relative URL field.
    • For the Tomcat Web Server, type /CalculatorWS?Tester in the Relative URL field.

    Note: Since the result of a deployed EJB module is not displayed in a browser, you cannot take the step above if you are working with an EJB module.

  2. Right-click the project node and choose Run Project.

    The IDE starts the application server, builds the application, and opens the tester page in your browser, if you deployed a web application to the Sun Java System Application Server. For the Tomcat Web Server and deployment of EJB modules, the situation is different:

    • If you deployed to the Tomcat Web Server, you will see the following instead, which indicates that you have successfully deployed your web service:

      Web page displayed when web service was successfully deployed to Tomcat server

    • If you deployed an EJB module, successful deployment is indicated by the following messages in the Output window:
          Deployment of application CalculatorWSApplication  completed successfully
          Enable of CalculatorWSApplication in target server   completed successfully
          Enable of application in all targets  completed successfully
          All operations completed successfully
          run-deploy:
          run:
          BUILD SUCCESSFUL
    • If you deployed to the Sun Java System Application Server, type two numbers in the tester page, as shown below:

      Web service tester page when service successfully deployed to Sun Java System Application Server

      The sum of the two numbers is displayed:

      Web page showing result of web service test

Summary

In this exercise, you deployed a web service and tested it.

Consuming the Web Service

Now that we have deployed our web service, we need to create a client to make use of the web service's add method. Here, we create three clients— a Java class in a Java SE application, a servlet, and a JSP page in a web application.

Client 1: Java Class in Java SE Application

  1. Choose File > New Project (Ctrl-Shift-N). Select Java Application from the General category. Name the project CalculatorWS_Client_Application.

    Note: At the time of writing, issue Issue 10 was unresolved; therefore, you must create your web service client in a project folder that does not contain spaces in its path. For example, the path should not be "C:\Documents and Settings\...".

    Click Finish.
  2. Right-click the CalculatorWS_Client_Application node and choose New > Web Service Client.
  3. In Project, click Browse. Browse to the web service that you want to consume. When you have selected the web service, click OK.
  4. Type org.me.calculator.client in Package, and click Finish.

    The Projects window displays the new web service client:

    New web service client in Java SE application displayed in the Projects window

  5. Double-click Main.java so that it opens in the Source Editor. Delete the TODO comment and right-click in that line. Choose Web Service Client Resources > Call Web Service Operation.
  6. Browse to the Add operation and click OK.
  7. Change the line that is underlined in red to the following:
        System.out.println("Sum: " + port.add(3,4));
  8. Right-click the project node and choose Run Project.

    The Output window should now show the following:

        compile:
        run:
        Sum: 7
            BUILD SUCCESSFUL (total time: 1 second)

Client 2: Servlet in Web Application

  1. Choose File > New Project (Ctrl-Shift-N). Select Web Application from the Web category. Name the project CalculatorWSServletClient.

    Note: At the time of writing, issue Issue 10 was unresolved; therefore, you must create your web service client in a project folder that does not contain spaces in its path. For example, the path should not be "C:\Documents and Settings\...".

    Click Finish.

  2. Right-click the CalculatorWSServletClient node and choose New > Web Service Client.
  3. In Project, click Browse. Browse to the web service that you want to consume. When you have selected the web service, click OK.
  4. Type org.me.calculator.client in Package, and click Finish.

    The Projects window displays the new web service client:

    New web service client in servlet displayed in the Projects window

  5. Right-click the project node and choose New > Servlet. Name the servlet ClientServlet and house it in a package called org.me.calculator.client. Click Finish. To make the servlet the entry point to your application, right-click the project node, choose Properties, click Run, and type /ClientServlet in Relative URL. Click OK.
  6. In the Source Editor, remove the line that comments out the body of the processRequest method. This is the line that starts the section that comments out the code:
        /* TODO output your page here

    Next, delete the line that ends the section of commented out code:

        */

    Add some empty lines after this line:

        out.println("<h1>Servlet ClientServlet at " + request.getContextPath () + "</h1>");

    Now, right-click in one of the empty lines that you added. Choose Web Service Client Resources > Call Web Service Operation. The Select Operation to Invoke dialog box appears.

  7. Browse to the add operation and click OK.

    The processRequest method now looks as follows (the added code is in bold below):


    1.     protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    2.     throws ServletException, IOException {
    3.         response.setContentType("text/html;charset=UTF-8");
    4.         PrintWriter out = response.getWriter();
    5.         out.println("<html>");
    6.         out.println("<head>");
    7.         out.println("<title>Servlet ClientServlet</title>");
    8.         out.println("</head>");
    9.         out.println("<body>");
    10.         out.println("<h1>Servlet ClientServlet at " + request.getContextPath () + "</h1>");
    11.  
    12.         try { // Call Web Service Operation
    13.             org.me.calculator.client.CalculatorWSService service = new org.me.calculator.client.CalculatorWSService();
    14.             org.me.calculator.client.CalculatorWS port = service.getCalculatorWSPort();
    15.             // TODO initialize WS operation arguments here
    16.             int arg0 = 0;
    17.             int arg1 = 0;
    18.             // TODO process result here
    19.             int result = port.add(arg0, arg1);
    20.             System.out.println("Result = "+result);
    21.         } catch (Exception ex) {
    22.             // TODO handle custom exceptions here
    23.         }
    24.  
    25.         out.println("</body>");
    26.         out.println("</html>");
    27.         out.close();
    28.     }

    Change the value for arg0 and arg1 to other numbers, such as 3 and 4.

    Change the System.out.println statement to out.println.

    Add a line that prints out an exception, if an exception is thrown.

    The try/catch block should now look as follows (new and changed lines are highlighted):


    1.     try { // Call Web Service Operation
    2.         org.me.calculator.client.CalculatorWSService service = new org.me.calculator.client.CalculatorWSService();
    3.         org.me.calculator.client.CalculatorWSApplication port = service.getCalculatorWSApplicationPort();
    4.         // TODO initialize WS operation arguments here
    5.         int arg0 = 3;
    6.         int arg1 = 4;
    7.         // TODO process result here
    8.         int result = port.add(arg0, arg1);
    9.         out.println("<p>Result: " + result);
    10.     } catch (Exception ex) {
    11.         out.println("<p>Exception: " + ex);
    12.     }

  8. Right-click the project node and choose Run Project.

    The server starts, if it wasn't running already; the application is built and deployed, and the browser opens, displaying the calculation result.

Client 3: JSP Page in Web Application

  1. Choose File > New Project (Ctrl-Shift-N). Select Web Application from the Web category. Name the project CalculatorWSJSPClient.

    Note: At the time of writing, issue Issue 10 was unresolved; therefore, you must create your web service client in a project folder that does not contain spaces in its path. For example, the path should not be "C:\Documents and Settings\...".

    Click Finish.

  2. Right-click the CalculatorWSJSPClient node and choose New > Web Service Client.
  3. In Project, click Browse. Browse to the web service that you want to consume. When you have selected the web service, click OK.
  4. Type org.me.calculator.client in Package, and click Finish.

    The Projects window displays the new web service client.

  5. In the Web Pages folder, double-click index.jsp so that it opens in the Source Editor.
  6. In the Web Service References node, expand the node that represents the web service. The add operation, which you want to invoke from the client, is now exposed.
  7. Drag the add operation to the client's index.jsp page, and drop it below the H1 tags. The code for invoking the service's operation is now generated in the index.jsp page.

    Change the value for arg0 and arg1 to other numbers, such as 3 and 4.

  8. Right-click the project node and choose Run Project.

    The server starts, if it wasn't running already; the application is built and deployed, and the browser opens, displaying the calculation result:

    JSP page showing result 

    @http://www.netbeans.org/kb/55/websvc-jax-ws.html
2007/03/21 15:36 2007/03/21 15:36
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

Creating a Simple SOA Project with NetBeans Enterprise Pack

Contents

Overview

You will be creating a simple SOA project. You will add a WSDL file to your BPEL Module project. You use the Partner view to add the messages, partner link type, port type, and operation. Then you will create a composite application project and use the CASA editor to modify the project configuration. This tutorial also illustrates a basic scenario of how a File Binding Component can be used in a composite application.

Software Needed for this Tutorial

Before you begin, you must install the following software on your computer:

  • NetBeans IDE 5.5.1 Beta with NetBeans Enterprise Pack 5.5.1 Beta

 

Configuring the Tutorial Environment

Before you can deploy your application, the Sun Java System Application Server and JBI runtime must be configured correctly and running.

To configure the tutorial environment:

  1. Click the Runtime tab to open the Runtime window.
  2. In the Runtime window, expand the Servers node.
  3. If the Servers node already contains a Sun Java System Application Server 9 node, then go to step 5.
  4. If the Servers node does not contain a Sun Java System Application Server 9 node, then do the following to add an application server:
    1. Right-click the Servers node and choose Add Server from the pop-up menu.
      The Add Server Instance dialog box opens.
    2. In the Choose Server page, from the Server drop-down list, select Sun Java System Application Server.
    3. (Optional) In the Name field, accept the default value or type the name you want to use to identify the server in the IDE.
    4. Click Next.
      The Platform Location Folder page opens.
    5. In the Platform Location field, use the Browse button to navigate to and select the Application Server installation location.
      If you accepted the default values during the installation, the location is C:\Sun\Appserver .
    6. Select the Register Local Default Domain radio button.
    7. Click Next.
    8. Supply the user name and password for the domain's administrator.
      If you accepted the default values during the installation, the user name is admin and the password is adminadmin .
    9. Click Finish.
  5. In the Runtime window, right-click the Sun Java System Application Server 9 node and choose Start.
    If the Start option is not available, the server is already running and you can skip the next step.
  6. Wait until the following message appears in the Output window:
    Application server startup complete.
    When the server is running, the IDE displays a green arrow badge on the Sun Java System Application Server 9 node.

Creating the Project

In this section, you create a BPEL Module project called HelloSample .

To create the HelloSample project:

  1. From the IDE's main menu, choose File > New Project.
    The New Project wizard opens.
  2. In the Categories list, select the Service Oriented Architecture node.
  3. In the Projects list, select the BPEL Module node.
  4. Click Next.
  5. In the Project Name field, type HelloSample .
  6. (Optional) In the Project Location field, use the Browse button to navigate to and select a different folder where the IDE will store the project files.
  7. Click Finish.
    The Projects window now contains a project node for a BPEL Module project called HelloSample .

Creating the WSDL Document

In this section, you add a WSDL file to your BPEL Module project and then use Partner view to configure the components of the WSDL Document.

To create HelloSample.wsdl :

  1. In the Projects window, expand the HelloSample project node, then right-click the Process Files node and choose New > WSDL Document.
    The New WSDL Document wizard opens.
  2. In the File Name field, type HelloSample .
  3. Click Finish.
  4. The IDE does the following:
    • Creates HelloSample.wsdl node under the Process Files.
    • Opens the HelloSample.wsdl in the source editor.
      The Source Editor contains 3 tabs for the WSDL file, Source, WSDL, and Partner, with the WSDL view opened.
    • Opens the Properties window. If the Properties window is not visible, choose Window > Properties.
  5. In the WSDL view, click the Partner button to open the Partner view of the WSDL editor.
    The IDE opens the WSDL Palette. If the Palette window is not visible, choose Window > Palette from the main menu.
    You can create the SequenceDiagram in this view.

To add Messages :

  1. In the Palette of the Partner view select the Message icon.
  2. Drag your selection to the WSDL Partner View design area, below the Messages.
    The IDE adds a Message and the name of the new Message is ( Messages1 ).
  3. Click the down arrow to expand the new message. If the arrow is up, the message is already expanded.
    The design area now shows Part Name and Part element or Type columns.
  4. In the Message Part Name column, double-click the default value (part1) to make the field editable.
  5. Type inputType and press Enter. If the Message1 is collapsed, click the down arrow to expand the new message
  6. In the Part Element Or Type column, make sure the default type is xsd:string
    If the type is not string then click the ellipsis button and select BuiltIn Schema Types > Built-in Types > String
  7. Repeat step 1-6 and for the Message Part Name, enter resultType.

To add PartnerLinkType :

  1. In the Palette of the Partner view select the PartnerLinkType icon.
  2. Drag your selection to the WSDL Partner View design area, below the PartnerLinkTypes(0).
    The IDE adds a PartnerLink and is ready to create new Roles and Port Types. Roles and PortTypes are drawn as dotted vertical lines( Lifeline) with the External names showing at the top.
  3. For Port Types double click the green rectangle under the role1 node.
  4. Click Enter. The new portType1 is assigned.
  5. In the Palette of the Partner view select the Request-Response icon.
  6. Drag your selection to the WSDL Partner View design area, below the portType1.
    The new Operation, operation1 is added.
  7. Under operation1, double click the upper message arrow where it says <No Message Selected> and select tns:message1.
  8. Repeat step 7and 8 for the lower message arrow and select tns:message2.

Creating the BPEL Process

To create HelloSample.bpel :

  1. In the Projects window, expand the HelloSample project node, then right-click the Process Files node and choose New > BPEL Process.
    The New BPEL Process wizard opens.
  2. In the File Name field, type HelloSample.
  3. Click Finish.
    The Sample.bpel is created

To add a partner link:

  1. In the Web Service section of the Palette, select the Partner Link icon and drag your selection to the design area.
    The Create New Partnerlink1Property Editor opens.
  2. Accept the defaults and click OK.

To add a Receive activity:

  1. In the Web Service section of the Palette, select the Receive icon and drag your selection to the design area between the Process Start activity and the Process End activity.
    The IDE provides you with visual clues to show you where you can drop the selection.
    This action places a Receive activity called Receive1 in the Design view.
  2. Double-click the Receive1 activity.
    The Receive1 [Receive] - Property Editor opens.
  3. From the Partner Link drop-down list, select PartnerLink1.
    The IDE fills in the Operation field.
  4. Create a new input variable by doing the following:
    1. Click the Create button next to the Input Variable field.
      The New Input Variable dialog box opens.
    2. Change the value in the Name field to inputVar .
    3. Click OK.
  5. Click OK to close the Receive1 [Receive] - Property Editor.
    The Receive activity is now labeled start in the Design view.

To add a Reply activity:

  1. In the Web Service section of the Palette, select the Reply icon and drag your selection to the design area between the Receive1 activity and the Process End activity.
    The IDE provides you with visual clues to show you where you can drop the selection.
    This action places a Reply activity called Reply1 in the Design view.
  2. Double-click the Reply1 activity.
    The Reply1 [Reply] - Property Editor opens.
  3. From the Partner Link drop-down list, select PartnerLink1.
    The IDE fills in the Operation field.
  4. Create a new output variable by doing the following:
    1. Make sure the Normal Response radio button is selected.
    2. Click the Create button next to the Output Variable field.
      The New Output Variable dialog box opens.
    3. Change the value in the Name field to outputVar .
    4. Click OK.
  5. Click OK to close the Reply1 [Reply] - Property Editor.
    The Reply activity is now labeled end in the Design view.

To add an Assign activity:

  1. In the Basic Activities section of the Palette, select the Assign icon and drag your selection to the design area between the Receive1 activity and the Reply1 activity.
    This action places an Assign activity called Assign1 in the Design view.
  2. Select the Assign1 activity.
  3. If the BPEL Mapper window is not visible, choose Window > BPEL Mapper from the main menu.
  4. In the left pane of the BPEL Mapper, under Variables, expand the inputVar node.
    inputType appears under inputVar .
  5. In the right pane of the BPEL Mapper, under Variables, expand the outputVar node.
    resultType appears under outputVar .
  6. Drag inputType from the left pane of the BPEL Mapper to the resultType node in the right pane of the BPEL Mapper.
    This assignment copies the input statement into the output.
  7. To save your changes, in the Projects window, select the SynchronousSample project node, and from the IDE's main menu, choose File > Save All.

Creating the Composite Application

Before you deploy the BPEL Module project, you must add the JBI module to the deployment project. Deploying the project makes the service assembly available to the application server, thus allowing its service units to be run.

To create the Composite Application project:

  1. From the IDE's main menu, choose File > New Project.
    The New Project wizard opens.
  2. In the Categories list, select the Service Oriented Architecture node.
  3. In the Projects list, select the Composite Application node.
  4. Click Next.
  5. In the Project Name field, type SampleCompositeApp .
  6. Click Finish.
    The Projects window now contains a project node for a Composite Application project called SampleCompositeApp .

Using the CASA Editor

To use the CASA editor to modify the project configuration:

  1. Right click on the SampleCompositeApp project and select Edit Project.
  2. Click on the HelloSample node and drag-n-drop it onto the JBI module area.



  3. Click the build button on CASA toolbar to build the bpel project.

To create the WSDL endpoint:

  1. Click on the "file" palette item on the WSDL Bindings category in the Palette panel.
  2. Drag-n-drop it to the WSDL Ports area in the CASA editor.
  3. A new "casasport1" WSDL endpoint is added.

To createa new connection:

  1. Click on the consume endpoint of the new port.
  2. Drag it to the erole1_myRole to create a new connection.

To Check auto-generated WSDL endpoint properties

  1. In the Navigator panel, expand the WSDL Ports node.
  2. Expand casaPort1 > casaBinding1 > operation1 > input1.
  3. Select file:message.
  4. In the Properties window, assign use='literal" , pollingIntervl=5000 and fileName=input.txt.
  5. Click on WSDL Ports area in the CASA editor to open the Navigator panel again.
  6. In the Navigator panel, expand WSDL Ports > casaPort1 > casaBinding1 > operation1 > output1.
  7. Select file:message.
  8. In the Properties window, assign fileName=output.txt.
  9. Click on WSDL Ports area in the CASA editor to open the Navigator panel.
  10. In the Navigator panel, expand the WSDL Ports node.
  11. Expand casaPort1 ->casaPort1 to select the file:address node.
  12. In the Properties window, in the fileDirectory, replace C:/Temp with the string c:/temp.
  13. Click Ok.



Deploying and Testing the SampleCompositeApp

To deploy the Composite Application:

  1. Right-click the SampleCompositeApp project node and choose Deploy Project.
    If a message similar to the following message appears in the Output window, then the deployment has succeeded:
    BUILD SUCCESSFUL (total time: 11 seconds)

To test the SampleCompositeApp:

  1. Create the input.txt file in c:/temp folder and edit the file to content 'Hello World!!'.
  2. input.txt will be renamed to input.txt_processed.
  3. output.txt will be created in the same folder with the same content 'Hello World!!'.


@http://blogs.sun.com/barkodar/resource/HelloSample.html

2007/03/21 15:16 2007/03/21 15:16
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

QUEUE와 DELAYED 프로세싱

J2SE 5.0 출시에는 새로운 top-level Queue 인터페이스가 Collections Framework에 추가되어 Map, List, Set 인터페이스와 어우러진다. 일반적으로 queue는 먼저 들어온 것이 먼저 나가는 데이터 스트럭쳐이지만 priority queue같은 몇몇 구현들에서는 queue 뒤에 엘리먼트가 첨부되지 않는다. 이 queue와 FIFO(first in, first out)구조에 관한 얘기는 은행에서의 대기선에 비유할 수 있겠다. 은행직원은 고객이 대기선에 있는지 확인한 후 대기선의 첫번째 손님을 맞이하여 손님이 원하는 거래를 처리한다. 그리고 그 손님은 이제 대기선에서 제외된다.

J2SE 5.0에는 Queue 인터페이스와 함께 몇 가지 새로운 queue 구현이 있다. DelayQueue가 그 중 하나인데, DelayQueue에서 queue 안의 아이템들은 지연시간 동안 처리되지 않는다. 이번 테크팁에서는 새로운 Queue 인터페이스와 DelayQueue 구현에 대해 알아보도록 하자.

첫번째로 Queue 인터페이스를 분석해보자. 이 인터페이스는 Collection을 확장하고 다섯개의 고유 메서드들을 추가한다.

  • E element()
  • boolean offer(E o)
  • E peek()
  • E poll()
  • E remove()

J2SE 5.0이 새롭게 generics를 지원하므로 여기에서의 E는 어느 타입이든지 가능하며, Queue가 생성될 때 정의된 엘리먼트 타입으로 결정된다.

Queue의 엘리먼트를 추가하고 제거하는 데 당연히 Collection 인터페이스 메서드들을 사용할 수도 있지만, 그 메서드들은 동작할 때 부가적인 요구사항을 가지므로, Queue 인터페이스에서는 사용하지 않을 것을 권장하고 있다. 예를 들어 Collection.add 메서드로 queue에 엘리먼트를 추가하는 대신에 offer 메서드로 queue에 엘리먼트를 추가할 수 있다. 이 둘은 무슨 차이가 있을까? add 실행이 오류가 날 수 있다. 그 한 예는 queue에 사이즈 제한이 있을 때이다.(은행 대기선에 비유하자면, 10명만 대기 가능할 경우) Collectionadd 메서드를 사용하면 add는 예외를 던지면서 실패한다. 이와 비교할 때 offer 메서드는 false를 리턴하며 "실패"하게 된다. 따라서 offer 메서드를 사용하면 실제로 예외적인 상황에서만(특히 체크 안 된 런타임 예외가 던져졌을 경우) 예외처리(exception handling)을 사용하게 된다.

Queue의 다른 네가지 메서드는 두개씩 짝지어 설명할 수 있다. remove/poll, element/peek. removepoll 메서드는 둘 다 queue의 첫번째 엘리먼트 즉 "head"를 제거하는 데 사용된다. 빈 Collection 객체에서 호출되었을 때, remove 메서드는 예외를 던지고, poll 메서드는 단순히 null 값을 리턴한다. head 엘리먼트를 제거하는 대신 단지 그 엘리먼트를 살펴볼 수도 있다. 이 때 element와 peek 메서드가 사용된다. 여기서 element 메서드는 빈 queue에서는 예외를 던지고, peek은 null값을 리턴한다. Queue는 일반적으로 태스크를 진행하는 데 사용되므로 빈 queue를 갖는 것이 예외상황일 필요는 없다. 따라서, poll/peek 모델이 사용하기에 보다 적합할 것이다. (앞에서 본 메서드들 중 예외를 안 던지고 null 리턴하는 메서드들)

Queue는 다음과 같은 상황에서 일반적으로 사용된다.

   class Producer implements Runnable {
     private final Queue queue;
     Producer(Queue q) { queue = q; }
     public void run() {
       try {
         while(true) { queue.offer(produce()); }
       } catch (InterruptedException ex) { ... handle ...}
     }
     Object produce() { ... }
   }

   class Consumer implements Runnable {
     private final Queue queue;
     Consumer(Queue q) { queue = q; }
     public void run() {
       try {
         Object o;
         while((o = queue.poll()) != null) { consume(o); }
       } catch (InterruptedException ex) { ... handle ...}
     }
     void consume(Object x) { ... }
   }

Queue가 꽉 차 있거나(생산자의 입장에서) 비어있을 때(소비자의 입장에서) 어떤 일이 일어나는 지 궁금할 것이다. 이 시점에서 새로운 queue 인터페이스 BlockingQueue를 설명하는 것이 좋겠다. Queue를 사용하여 엘리먼트를 무작정 추가하거나(offer사용) 삭제하는(poll 사용) 대신 BlockingQueueput 메서드로 엘리먼트를 추가하고 take메서드로 제거할 수 있다. puttake는 모두 이를 호출한 쓰레드가, 특정 조건 하에서 블로킹되게끔 한다. put은 queue가 꽉 차 있을 경우, take는 queue가 비어있을 경우가 블로킹 조건이다.

BlockingQueue의 일반적인 사용패턴은 다음과 같다.

   class Producer implements Runnable {
     private final BlockingQueue queue;
     Producer(BlockingQueue q) { queue = q; }
     public void run() {
       try {
         while(true) { queue.put(produce()); }
       } catch (InterruptedException ex) { ... handle ...}
     }
       Object produce() { ... }
  }
  
   class Consumer implements Runnable {
     private final BlockingQueue queue;
     Consumer(BlockingQueue q) { queue = q; }
     public void run() {
       try {
         while(true) { consume(queue.take()); }
       } catch (InterruptedException ex) { ... handle ...}
     }
     void consume(Object x) { ... }
   }

각 생성된 생산자가 꽉 찬 queue에 새로운 아이템을 추가하려 하면 put메서드에서 기다리고, take 메서드에서는 꺼내갈 것이 추가될 때까지 기다린다. queue가 비어있다면 while(true) 조건문에는 아무런 변화도 일어나지 않을 것이다.

DelayQueue는 BlockingQueue 인터페이스의 구체적인 구현이다. DelayQueue 에 추가된 아이템들은 반드시 새로운 Delayed 인터페이스를 구현해야하며, 이 Delayed는 한 개의 메서드, long getDelay(TimeUnit unit)를 갖고 있다. DelayQueue는 우선순위 힙 데이터 스트럭쳐에 기반한 시간 기준 스케쥴링 Queue로 동작한다

데모를 위해, 다음의 프로그램 DelayTest는 몇 초안에 실행되는 Delayed 인터페이스를 구현한다. 알아둬야할 것은1) nanosecond는 10억분의 1초, 2) nanosecond 유니트에서 작업을 가능케하는 System의 새로운 메서드, nanoTime 이 있다는 것이다. getDelay 메서드가 nanosecond로 리턴된 횟수를 필요로 하기 때문에 nanosecond에서 작업하는 것이 중요하다.

   import java.util.Random;
   import java.util.concurrent.Delayed;
   import java.util.concurrent.DelayQueue;
   import java.util.concurrent.TimeUnit;

   public class DelayTest {
     public static long BILLION = 1000000000;
     static class SecondsDelayed implements Delayed { 
       long trigger;
       String name;
       SecondsDelayed(String name, long i) { 
         this.name = name;
         trigger = System.nanoTime() + (i * BILLION);
       }
       public int compareTo(Delayed d) {
         long i = trigger;
         long j = ((SecondsDelayed)d).trigger;
         int returnValue;
         if (i < j) {
           returnValue = -1;
         } else if (i > j) {
           returnValue = 1;
         } else {
           returnValue = 0;
         }
         return returnValue;
       }
       public boolean equals(Object other) {
         return ((SecondsDelayed)other).trigger == trigger;
       }
       public long getDelay(TimeUnit unit) {
         long n = trigger - System.nanoTime();
         return unit.convert(n, TimeUnit.NANOSECONDS);
       }
       public long getTriggerTime() {
         return trigger;
       }
       public String getName() {
         return name;
       }
       public String toString() {
         return name + " / " + String.valueOf(trigger);
       }
     }
     public static void main(String args[]) 
             throws InterruptedException {
       Random random = new Random();
       DelayQueue<SecondsDelayed> queue = 
             new DelayQueue<SecondsDelayed>();
       for (int i=0; i < 10; i++) {
         int delay = random.nextInt(10);
         System.out.println("Delaying: " + 
               delay + " for loop " + i);
         queue.add(new SecondsDelayed("loop " + i, delay));
       }
       long last = 0;
       for (int i=0; i < 10; i++) {
         SecondsDelayed delay = (SecondsDelayed)(queue.take());
         String name = delay.getName();
         long tt = delay.getTriggerTime();
         if (i != 0) {
           System.out.println("Delta: " + 
                 (tt - last) / (double)BILLION);
         }
         System.out.println(name + " / Trigger time: " + tt);
         last = tt;
       }
     }
   }

DelayTest 프로그램은 엘리먼트를 실행하기 전 DelayQueue 안에 그 10개의 엘리먼트를 위치시킨다.

다음은 DelayQueue를 한번 구동했을 때의 출력물이다.

   Delaying: 8 for loop 0
   Delaying: 7 for loop 1
   Delaying: 2 for loop 2
   Delaying: 4 for loop 3
   Delaying: 0 for loop 4
   Delaying: 9 for loop 5
   Delaying: 3 for loop 6
   Delaying: 4 for loop 7
   Delaying: 6 for loop 8
   Delaying: 2 for loop 9
   loop 4 / Trigger time: 1883173869520000
   Delta: 1.9995545
   loop 2 / Trigger time: 1883175869074500
   Delta: 0.0012475
   loop 9 / Trigger time: 1883175870322000
   Delta: 0.9995177
   loop 6 / Trigger time: 1883176869839700
   Delta: 0.9995187
   loop 3 / Trigger time: 1883177869358400
   Delta: 6.408E-4
   loop 7 / Trigger time: 1883177869999200
   Delta: 2.0001667
   loop 8 / Trigger time: 1883179870165900
   Delta: 0.9986953
   loop 1 / Trigger time: 1883180868861200
   Delta: 0.9995595
   loop 0 / Trigger time: 1883181868420700
   Delta: 1.001262
   loop 5 / Trigger time: 1883182869682700

이 출력물은 loop4를 위한 아이템이 time 0, 즉 지연 없이 시작하기로 설정되어있다는 것을 가리키고 있으며,

   Delaying: 0 for loop 4

따라서 첫번째로 다음과 같이 구동한다.

   loop 4 / Trigger time: 1883173869520000

Loop 2에서는 2초간의 지연이 있으며,

   Delaying: 2 for loop 2

따라서 다음과 같이 나타난다.

   loop 2 / Trigger time: 1883175869074500

여기서의 delta는 1.9995545로 약 2초이다.

   Delta: 1.9995545

다른 loop를 위한 비슷한 delta들도 존재한다.

좀 더 실제적인 예를 위해 DelayQueue에서 pull된 것을 단지 출력하는 대신, queue의 아이템들을 Runnable 구현시키고, 그 아이템들의 run 메서드를 호출할 수 있다.

Queue, DelayQueue 와 J2SE 5.0에서 바뀐 다른 Collections Framework에 대한 좀 더 많은 정보를 원한다면 Collection Framework Enhancements를 참조하기 바란다.


@http://kr.sun.com/developers/techtips/c2004_1019.html

2007/03/16 18:01 2007/03/16 18:01
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

HTTPURLCONNECTION를 사용하여 웹 페이지 액세스하기

이 글은 HttpURLConnection 과 이의 서브클래스인 HttpsURLConnection 을 사용하여 보안 웹 페이지에 액세스하는 방법을 보여준다. 또한 비보안 페이지(non-secure page)에서 보안 페이지(secure one)로의 리다이렉트를 쉽게 할 수 있는 방법도 볼 수 있다. HTTP 와 HTTPS에 관한 정보는 HTTP 1.1 RFC 2616HTTPS RFC 2818를 참고하기 바란다.

첫번째 예로, 주어진 URL에 접속하기 위해 다음 WebPageReader 프로그램의 HttpURLConnection 를 이용해 보자. 그리고 페이지의 내용을 스탠다드 아웃(standard out)에 출력하자.

[code] import java.net.URL; import java.net.MalformedURLException; import java.net.URLConnection; import java.io.IOException; import java.io.BufferedReader; import java.io.InputStreamReader; public class WebPageReader { private static URLConnection connection; private static void connect( String urlString ) { try { URL url = new URL(urlString); connection = url.openConnection(); //for jdk 1.5 or higher connection.setConnectionTimeout(1000); connection.setReadTimeout(3000); //for jdk 1.4 above System.setProperty("sun.net.client.defaultConnectTimeout", "10000"); System.setProperty("sun.net.client.defaultReadTimeout", "50000"); } catch (MalformedURLException e){ e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static void readContents() { BufferedReader in = null; try { in = new BufferedReader( new InputStreamReader( connection.getInputStream())); String inputLine; while ( (inputLine = in.readLine()) != null) { System.out.println(inputLine); } } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { if (args.length != 1) { System.err.println("usage: java WebPageReader " + "<url>"); System.exit(0); } connect(args[0]); readContents(); } } [/code]

만약 현재의 위치가 방화벽 뒤라면, 다음과 같이 설정된 proxyHost과 proxyPort 변수들이 필요하다.

[code] http.proxyHost=webcache http.proxyPort=8080 https.proxyHost=webcache https.proxyPort=8080 [/code]

커맨드 라인에 -D플래그를 이용해서 값을 직접 입력하거나 프로그램 상에서 System.setProperty()를 호출함으로써 변수를 구할 수있다. WebPageReader 를 컴파일한 후에 이하와 같은 커맨드로 Core Java Technologies Tech Tips 홈 페이지의 내용을 열거해 볼 수 있다.

[code] java WebPageReader http://java.sun.com/developer/JDCTechTips/ [/code]

URLConnection는 추상 클래스이다. URL클래스의 openConnection() 메소드는 지정된 URL을 읽을 수 있도록 적절하고 구체적인 서브클래스를 리턴한다. http나 https URL을 입력하면 이는 HttpURLConnection나 HttpsURLConnection의 서브클래스가 될 것이다. 만약 다음을 openConnection()를 호출하는 라인에 추가하면,

[code] System.out.println(connection.getClass()); [/code]

HttpURLConnection의 숨겨진 구현 클래스의 인스턴스를 리턴하는 커넥션(connection)을 보게 된다. 예를 들면, 다음과 같다.

[code] class sun.net.www.protocol.http.HttpURLConnection [/code]

이와 유사하게 보안 페이지를 읽기 위해 동일한 WebPageReader코드를 사용할 수가 있다.

[code] java WebPageReader https://today.dev.java.net [/code]

후자의 경우, 커넥션은 HttpsURLConnection의 서브클래스인 HttpURLConnection타입이라는 것을 알아야 한다. 보다 명확하게 말하자면 다음과 같은 숨어있는 구현 클래스가 있다는 것을 인식할 수 있어야 한다.

[code] class sun.net.www.protocol.https.HttpsURLConnectionImpl [/code]

일반적으로 브라우저에 URL을 입력할 때, 이동하고자하는 페이지가 보안 페이지인지 아닌지는 알 수가 없다. 다시 말하면, today.dev.java.net 페이지를 보기 위해서는 http://today.dev.java.net를 입력한다. 필요하다면 브라우저가 리다이렉트할 것이고 사용자를 https://today.dev.java.net로 연결하기 위해 적절한 신호변경을 수행한다. WebPageReader프로그램이 요청된 리다이렉션을 수행하는지를 살펴보자.

[code] java WebPageReader http://today.dev.java.net [/code]

원하는 페이지로 리다이렉트되는 대신에 다음과 같은 메시지를 보게 된다.

[code] <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <HTML><HEAD> <TITLE>301 Moved Permanently</TITLE> </HEAD><BODY> <H1>Moved Permanently</H1> The document has moved <A HREF="https://today.dev.java.net/">here</A>.<P> <HR> <ADDRESS> Apache/1.3.26 Server at today.dev.java.net Port 80 </ADDRESS> </BODY></HTML> [/code]

이 정보로부터 무언가를 읽어내는 것은 어렵지만 문제는 리다이렉션에 관한 것이 아니다. URL http://linux.java.net으로 프로그램을 실행하면, 프로그램은 http://community.java.net/linux으로 적절히 이를 리다이렉트하고 사용자는 원하는 컨텐츠를 볼 수가 있다. 어떤 일이 일어나는지를 자세히 살펴보려면 HttpURLConnection를 명시적으로 이용해야 한다. 스탠다드 아웃에 웹 페이지의 컨텐츠를 출력하는 코드를 삭제해서 일을 간단히 해보자. RedirectingReader프로그램이다.

[code] import java.net.URL; import java.net.MalformedURLException; import java.net.HttpURLConnection; import java.io.IOException; public class RedirectingReader { private static HttpURLConnection connection; private static void connect( String urlString ) { try { URL url = new URL(urlString); connection = (HttpURLConnection)url.openConnection(); //for jdk 1.5 or higher connection.setConnectionTimeout(1000); connection.setReadTimeout(3000); //for jdk 1.4 above System.setProperty("sun.net.client.defaultConnectTimeout", "10000"); System.setProperty("sun.net.client.defaultReadTimeout", "30000"); System.out.println(connection.getURL()); System.out.println( connection.getResponseCode() + " " + connection.getResponseMessage()); System.out.println(connection.getURL()); } catch (MalformedURLException e){ e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { if (args.length != 1) { System.err.println( "usage: java WebPageReader " + "<url>"); System.exit(0); } connect(args[0]); } } [/code]

다음과 같이 리다이렉트하는 URL을 입력하여 RedirectingReader 를 컴파일하고 실행해 보자.

[code] java RedirectingReader http://linux.java.net/ [/code]

다음과 같은 출력값을 보게 될 것이다.

[code] http://linux.java.net/ 200 OK http://community.java.net/linux/ [/code]

첫번째 라인이 재빨리 나타난다. String값으로 URL을 생성하고 HttpURLConnection객체를 실행하자. 그러면 http://linux.java.net를 요청하는 동안에 잠깐의 멈춤이 생긴다. 페이지가 리다이렉트되는 이 시간동안 받게 되는 응답 코드와 메시지는 리다이렉트된 페이지로부터 온 것이다. 이 리다이렉트된 페이지는 출력값의 3번째 라인에 열거된다. URL url = new URL(urlString);아래의 라인을 추가해서 리다이렉션을 허용하지 않았을 때 발생하는 현상을 보자.

[code] HttpURLConnection.setFollowRedirects(false); [/code]

출력값은 다음과 같다.

[code] http://linux.java.net/ 302 Found http://linux.java.net/ [/code]

이는 302 에러가 발생했다는 것을 나타낸다. 곧 리다이렉트되지 않고 URL이 그대로 유지되었다는 것이다. 이를 처리하기 전에, 좀 전에 추가했던 라인을 지우고 리다이렉션이 다시 작동하는지를 확인하기 위해 RedirectingReader 프로그램을 실행시켜보자. RedirectingReader를 다시 한번 실행시키고, http://today.dev.java.net 를 입력하자. 다음과 같은 출력값을 보게 된다.

[code] http://today.dev.java.net 301 Moved Permanently http://today.dev.java.net [/code]

위는 이 프로그램이 "Moved Permanently" 에러를 처리할 수 없어서 리다이렉트 했다는 것을 말한다. 이것이 바로 원했던 디폴트 속성이다. 보안문제 때문에 http 과 https간에는 리다이렉트할 수 없다. 어디로 리다이렉트할 것이냐하는 정보는 이 응답의 헤더 부분에 있다. 이전의 요청에 대한 전체 응답 헤더는 다음과 같다.

[code] HTTP/1.1 301 Moved Permanently Date: Tue, 03 Feb 2004 01:38:43 GMT Server: Apache/1.3.26 (Unix) mod_ssl/2.8.10 OpenSSL/0.9.6b mod_jk/1.2.1 Location: https://today.dev.java.net/ Content-type: text/html; charset=iso-8859-1 [/code]

HttpURLConnection 내의 getResponseCode() 과 getResponseMessage() 메소드가 이 응답의 첫번째 라인에 포함된 정보를 리턴하는 것을 본 적이 있을 것이다. 혹은 getHeaderField() 메소드를 이용해서 헤더 필드의 이름에 스트링값을 넣어주어도 된다. 가령, getHeaderField("Location")는 https://today.dev.java.net/값을 리턴한다.

이 글의 시작부분에서 언급했던 HTTP 1.1 과 HTTPS RFCs에서 요청과 응답 헤더의 포맷에 관해 자세히 살펴 볼 수 있다. 300 레벨 응답에서, "Location:"는 리다이렉션을 위한 위치값을 제공해야만 한다. 301나 302 에러를 발생하는지를 확인하기 위해 다음 사항을 추가하자.

[code] private static boolean mustRedirect(int code){ if (code == HttpURLConnection.HTTP_MOVED_PERM || code == HttpURLConnection.HTTP_MOVED_TEMP) { System.out.println("Received error " + code + ", trying secure redirect"); return true; } else return false; } [/code]

리다이렉트가 자동적으로 처리되지 않는다면 사용자는 301 나 302 응답 코드만을 받게 된다는 것을 기억하자. 지금까지 이것은 리다이렉트가 HttpURLConnection가 아닌 HttpsURLConnection가 필요하다는 것을 의미했다. "Location:" 필드에 제공된 정보를 따르자. 다음과 같이 새로운 정보를 이용해서 url 값과 커넥션을 재설정하자.

[code] url = new URL("https://"+ url.getHost() + url.getFile()); connection = (HttpsURLConnection)url.openConnection(); [/code]

마지막으로, 웹 리더를 받기 위해 위의 모든 사항을 모으고 필요할 때 보안 페이지로 리다이렉트될 수 있도록 하자.

[code] import javax.net.ssl.HttpsURLConnection; import java.net.URL; import java.net.MalformedURLException; import java.net.HttpURLConnection; import java.io.IOException; import java.io.BufferedReader; import java.io.InputStreamReader; public class RedirectingReader { private static HttpURLConnection connection; private static URL url; private static void connect(String urlString) { try { url = new URL(urlString); connection = (HttpURLConnection) url.openConnection(); //for jdk 1.5 or higher connection.setConnectionTimeout(1000); connection.setReadTimeout(3000); //for jdk 1.4 above System.setProperty("sun.net.client.defaultConnectTimeout", "10000"); System.setProperty("sun.net.client.defaultReadTimeout", "50000"); int code = connection.getResponseCode(); if (mustRedirect(code)) secureRedirect( connection.getHeaderField("Location")); readContents(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static boolean mustRedirect(int code) { if (code == HttpURLConnection.HTTP_MOVED_PERM || code == HttpURLConnection.HTTP_MOVED_TEMP) { return true; } else return false; } private static void secureRedirect(String location) throws IOException { System.out.println(location); url = new URL(location); connection = (HttpsURLConnection) url.openConnection(); } private static void readContents() { BufferedReader in = null; try { in = new BufferedReader( new InputStreamReader( connection.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println(inputLine); } } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { if (args.length != 1) { System.err.println("usage: java WebPageReader " + "<url>"); System.exit(0); } connect(args[0]); } } [/code]

업데이트된 RedirectingReader 를 컴파일하고 동작이 제대로 이루어지는지 확인하기 위해 몇 개의 다른 입력값을 넣어 실행해보자. 예를 들면 http://today.dev.java.net 와 http://linux.java.net를 넣어보자. 리다이렉트되지 않는 보안페이지와 비보안 페이지를 입력해서 RedirectingReader를 실행해도 동작이 적절하게 이루어져야 한다. 이제 다시 뒤로 돌아가서 최초 WebReader 프로그램에 모든 println() 메소드를 제거하고 readContents()를 추가할 수 있다.


@http://kr.sun.com/developers/techtips/c2004_02_10.html

2007/03/15 12:58 2007/03/15 12:58
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다
  1. Blog Icon
    감사합니다.

    좋은 정보 감사합니다. 비공개로 담아갑니다 ^^;

  2. Blog Icon
    비밀방문자

    관리자만 볼 수 있는 댓글입니다.

  3. Blog Icon
    비밀방문자

    관리자만 볼 수 있는 댓글입니다.

넷빈즈(NetBeans)를 구하고 설치 해 보자. v1.0

넷빈즈는 3.5 버전에 들어서면서 비약적인 성능 향상을 가져왔다.
그때 당시 개발 모토가 'Improve Perfomance' 였다고하니 SUN에서 얼마나
공을 들였는지 알만 하다. 덕분에 내가 넷빈즈에 빠져들게 되어버린 계기가 되었다(웃음)

지금도 마찬가지지만 개발 할때 코드를 만들어내는것도 재미있었지만
그에 못지않게 이런저런 IDE를 사용 하는것 역시 개발하는과정에서 맛보는 재미중의
하나였기 때문에 회사에서 특별히 개발툴을 지정하지 않으면 새 프로젝트 시작 할 때마다
다른 IDE를 사용 하고 있었다.

넷빈즈를 IDE로 결정한 그 당시 계획은 '다음번 프로젝트에선 Eclips 를 써봐야지' 라고 구상
하고 있었다..( 하지만 이 결심은 지켜지지 못했지만.. ^^ )

불행인지 다행인지 그때 넷빈즈 버전은 3.1 이었다. 사용하면서 이놈의 마이너스러움에
어찌나 빠져 들던지...

서두가 길었다.. 제목에 충실 해 지자..

------------------------------------------------------------------------

설치 진행에 앞서 기본적으로 jdk 1.4.2 이상이 설치 되어 있어야한다.
(설치에 필요한 권장 사항이다. 설치 후 프로젝트를 생성 하고 jdk를 바꿔가며
빌드 할 수 있으니 다른 버전의 jdk를 사용 한다고 해서 걱정하지말자.)
전에는 sun사이트에서 jdk와 netbeans를 묶은 패키지를 받을 수 있었는데
NetBeans를 완전히 NetBeans.org에서 관리 하도록 했는지 묶음 패키지를 받는
경로는 사라지고 없다..( 물론 archive를 뒤져보면 나오긴 하겠지만.. )
그리고 실무에서 개발을 하고 있는 상황이라면 프로젝트별로 사용하는 jdk버전이
있을텐데 괜히 묶여 나오면 설치가 꺼려지기도 할 것이다.
본인은 jdk가 번들되지 않은 netbeans + 개발자가 선택한 jdk버전 조합으로 가는게
옳다고 생각 하기 때문에 jdk와 netbeans는 따로 설치 할 수 있는 standalone버전으로
설명 할 것이다.

(물론 jdk가 설치되어 있지 않고, 학습이 목적이라면 jdk번들된 netbeans는 훌륭한
선택이 될 수 있을것이다.)

우선 http://www.netbeans.info/downloads/download.php?a=arch&p=1 에 들러
NetBeans 4.1을 다운받자.( 아니, 5.0이 릴리즈 된지도 꽤 되었고.. 5.5 릴리즈가 목전인데
왜 4.1 이냐고?  이유는 이미 http://www.yunsobi.com/tt/subby/2 에 밝혔다..)

netbeans.org의 메뉴구성도 뻑하면 바뀌는데 링크가 없어지더라도 놀라거나 하지 말고http://netbeans.org에서 다운로드 항목을 잘 좇아들어가면 받을 수 있을것이다.

netbeans 넷빈즈

자신의 os를 선택하고 현재 국제화 버전은 없으므로 영문판을 선택한다.
email 주소등은 기입하지 않아도 된다.

netbeans 넷빈즈

netbeans-4_1-windows.exe 를 선택하자.

netbeans 넷빈즈

SPL( SUN PUBLIC LICENCE ) 라이센스 동의 화면이 나오고 동의 하면

netbeans 넷빈즈
 
다운로드 페이지로 이동한다.
그럼 다운로드 받은 파일을 실행하여 설치를 진행 하자.

netbeans 넷빈즈

netbeans 넷빈즈

netbeans 넷빈즈

netbeans 넷빈즈

netbeans 넷빈즈

여기서 Default 로 사용 할 jdk버전을 선택한다.
여러 버전의 jdk를 사용하고 있다면 설치 후 프로젝트 단위로 jdk를 변경 할 수 있으니
여기선 설치에 권장하는 1.4.2 를 선택해 진행 한다.

netbeans 넷빈즈

netbeans 넷빈즈
 
설치 완료 화면.
windows 가 아닌 다른 OS라면
http://www.netbeans.org/community/releases/41/install.html
 문서를 참조하면 된다.
넷빈즈의 세계에 발을 들여 놓은 것을 축하한다.
앞으로 멋진 넷빈즈의 세계를 함께 탐험 해 보자.
 
ps. 개인적인 지식에는 한계가 있기 마련입니다. 제가 잘못 생각하고 있거나 다른점이 있다면
바로바로 알려주세요.
2007/02/28 13:08 2007/02/28 13:08
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

아파치 재단에 제로니모가 있다면.. 썬사에는 글래스피쉬가 있습니다.





JAVA EE 5 의 오픈소스 구현체인 글래스 피쉬..

http://java.sun.com/javaee/community/glassfish/
https://glassfish.dev.java.net/public/devindex.html

오픈소스 엔터프라이즈 어플리케이션 서버, 제로니모와 글래스피쉬의 선전을 기대 합니다.



2006/06/12 03:13 2006/06/12 03:13
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다