Programming/Java2007/10/11 17:09

출처 : Java Study Network
작성 :
조대협

1. WebLogic Class Loader

EJB와 Web Application을 Deploy하기 위해서는 효과적인 Packaging이 필요하다. 효과적인 Packaging을 위해서는 먼저 WAS의 ClassLoader의 구조에 대해서 알필요가 있는데, 먼저 WebLogic의 ClassLoader에 대해서 살펴보도록 하자.

○ Class Loader란?

Class Loader란 JAVA의 큰 장점중의 하나로, Compile Time이 아닌 Run Time에 Class를 Loading 할 수 있게 해주는 기술이다. 예를 들어, ClassA = new ClassA(); 라는 Code를 최초로 실행할때, JVM은 ClassA라는 Class를 Class Loader를 통해서, ClassA.class의 Byte Code를 최초로 Memory에 Load하게 된다. Class Loader는 이처럼, Class의 Byte Code를 File System이나,Jar와 같은 Archieve또는, Network Socket(Applet and RMI)를 통해서 동적으로 Loading 할 수 있도록 지원해준다.

이 Class Loader는 기술적으로 몇가지 특징을 가지고 있는데 그 내용을 살펴보면 다음과 같다.

- Hierarchical
: Class Loader는 Hierarchical 하게 생성이 가능하다. Parent Class Loader에서, Child Class Loader를 갖는것과 같이 Class Loader간의 계층형 구조를 갖게 되며, 최상위의 Class Loader는 "Bootstrap" Class Loader가 위치하게 된다.

- Delegate load request
: 위와 같이 Class Loader가 계층형 구조를 가지고 있기 때문에, Class 로딩상에 몇가지 규칙이 필요한데, 일정 시점에 Class Loading 요청을 받았을때, 상위 Class Loader가 Loading한 Class가 그 우선권을 가진다. 

예를 들어 설명하면, Class Loader가 parent부터, CL1-CL2-CL3 순서로 생성되어 있다고 가정하자, Application이 Class Loader CL3로 Class를 요청하면, CL3는 그 요청을 CL2로, CL2는 CL1으로 요청을 전달한다. 즉, Class Loading의 우선 순위는 Parent Class가 가지고 있고, 만약에 요청받은 Class가 없을 경우에만 아래 Level Class Loader가 Class를 Loading 하게 된다.

- Have visibility constraint
: 상위 Class Loader를 먼저 참조하는것에 이어서, Class Loader는 일종의 Scope Rule을 제공하는데, Child Class Loader는 Parent Class Loader의 Class를 Delegation Load Request를 이용하여 찾을 수 있지만, 그 반대로 Parent가 Child가 Loading한 Class를 사용할 수 는 없다. 또한 Parent의 같은 Level의 Child Class Loader는 서로 Loading한 Class를 사용할 수 없게 되어 있다.

- Cannot unload classes
: Class Loader에 의해서 Loading된 Class들은, Unload될 수 없다. Class Loader에는 Class Unloading기능이 없다. 그래서 이 Unloading 기능을 우회적으로 구현하는 방법은 Class를 Load한 Class Loader 자체를 삭제하고, 새로운 Class Loader를 만들어서 다시 Class를 Load 하면, Reload 되는 것처럼 작동하는 것이 된다.

내용이 좀 어려울 수 도 있겠지만, WLS의 뒤에 나올 Class Loader의 내용을 읽어보면 이해가 될 것이다. Deploy 개념을 이해하는데 중요한 내용이니 이해하도록 하자.

○ WebLogic의 Class Loader

그럼 이제 WebLogic의 Class Loader에 대해서 알아보도록 하자. 이 feature는 단지 WebLogic뿐 아니라, J2EE 표준을 따르는 WAS는 모두 준수하고 있는 내용이다.

일단 WebLogic이 기동되면 JVM Level의 Class Loader가 Loading된 후에, WebLogic의 Application에 따라 각각의 Class Loader가 그 Child로 Loading된다.

JVM Class Loader

먼저 JVM이 가동될때, Loading되는 Class Loader는 parent부터 순서대로, Bootstrap, Extensions, System Class Loader가 올라가게 된다. 그 내용을 살펴보자

- Bootstrap Class Loader
: JVM이 실행될 때 맨 처음 실행되는 Class Loader로, 가장 기본적인 JAVA 실행에 필요한 가장 기본적인 Class들을 (rt.jar, i18n.jar 와 같은 기본적인 Archieve) Loading 한다.

- Extensions Class Loader
: BootStrap Loading 후, 기본적으로 Loading되는 Class로 '$JAVA_HOME/lib/ext'에 있는 Class들이 Loading 된다. 이 Class들은 별도로 classpath에 잡혀 있지 않아도 Loading 된다.

- System Class Loader
: 다음으로, CLASSPATH에 정의되거나 JVM option에서 -cp, -classpath에 지정된 Class들이 로딩된다. 기본적으로 WebLogic은 이 JVM Level의 Class Loader에서 작동을 하게 되고, Application을 Deploy할 때마다 별도의 Class Loader를 System Class Loader의 Child로 Invoke하게 된다.

JVM Class Loader

WebLogic에서 Invoke되는 Class Loader는 종류에 따라 EJB-JAR, WAR, EAR 3가지로 구분이 된다. 각자의 Class Loader에 대해서 Check 해야 할 사항을 짚고 넘어가 보자.

- EJB-JAR
: 각 EJB-JAR File은 Deploy가 되면, JAR File 당 각각의 Class Loader를 생성하게 된다. 그래서, 다른 JAR File에 있는 Class들은 참조를 할 수 가 없고, 오로지 Parent Class Loader인, JVM Level의 CLASSPATH에 적용된 CLASS들만 참조를 할 수 있다. 그래서, 다른 EJB JAR File 내에 있는 EJB를 사용하기 위해서는 그 EJB의 Client Class들 (Remote Interface, Home Interace)을 같이 JAR로 묶어주어야 한다. 물론 같은 JAR File 내에 있는 EJB나 다른 Class를 사용하는 것은 같은 Class Loader상에 Load 된것이기 때문에, 가능하다.

- WAR
: Servlet이나 JSP를 Packaging 하는 WAR File 역시 EJB-JAR와 같은 특성을 갖는데, 집고 넘어가야 할 점은 Web Logic에서는 WAR에 대해서 우선순위 변경이 가능한데,일반적인 Class Loader의 우선 순위를 따르는 것 이외에, WEB-INF/classes와, WEB-INF/lib Directory가 우선순위를 갖는 것이 가능하다. 이 Directory 안에 Class가 있을 경우에는 Parent Class Loader에 Load된 Class보다 우선순위를 갖게 설정할 수 있다.이 설정은 We bLogic Console에서 PreferWebInfClasses 라는 Option을 true로 설정 (default는 false 이다.) 을 하면 가능하며, 자세한 내용은 이곳에서 Using PreferWebInfClasses in J2EE Applications 부분을 참고하기 바란다.

- EAR
: 위의 EJB-JAR와 WAR는 각각 하나의 Class Loader를 갖는데 반해서, EAR을 두개의 Class Loader를 갖게 된다. EJB-JAR를 위한 Class Loader와 WAR를 위한 Class Loader 두 개가 Invoke되고, 그 관계는 EJB-JAR Class Loader가 WAR Class Loader의 Parent 관계가 되서, Servet/JSP는 당연히 EJB Class를 참조해서 사용이 가능해지게 되는 것이다. (JSP는 WAR Class Loader에 의해 Loading 되었기 때문에, 그 Parent 인 EJB-WAR Class Loader에 의해 Loading 된 EJB Class를 사용할 수 있게 되는 것이다.)

 
<그림 1. WebLogic Class Loader 구조>

그럼 <그림 1>을 보자. 그림 1의 EJB JAR5는 EAR1이나 WAR4, EAR2의 Class Loader와 다른 Class를 사용하기 때문에, 다른 패키지의 Class를 참조할 수 없다.

EAR1의 WAR1은 EAR로 같은 Class Loader 상에 있는 EJB JAR1, EJB JAR2, EJB JAR3에 있는 Class를 참조할 수 있다. 그러나 EAR2의 Class는 참조할 수 없다. 그러나 역으로, EJB Class Loader가 WAR Class Loader의 Parent이기 때문에, EJB JAR 1.2.3는 WAR1,2의 Class를 참고할 수 없다.

여기서 한가지 집고 넘어가야할것은 모든 EJB JAR가 참조하는 Class들은 CLASSPATH내에 있는 Class가 우선시 된다. (JVM Class Loader가 모든 WebLogic Class Loader의 Parent이기 때문에.) 그래서, EJB의 Client Class나, Common Class들을 CLASSPATH와 JAR 양쪽에 넣으면 CLASSPATH내에 있는 CLASS가 참조가 된다. (이런 식의 Packaging은 권장하지 않는다. 상세한 내용은 다음에 나올 EJB Packaging 부분에서 알아보도록 하자)

※ WLS 8.1에서부터는 개발 환경을 위해서 Class Loader의 계층 구조를 임의로 지정할 수 있게 되어 있다. 자세한 내용은 이곳을 참고하기 바란다.

JVM Class Loader

J2EE에서, WAS가 하나의 Class Loader를 이용하지 않고, 각 WAR, EJB-JAR, EAR 별로 별도의 Class Loader를 사용하는 것은 다음과 같은 이유를 가지고 있다.

- Isolation
: 개발 그룹 A가 Application app-A에 대해서 개발과 Deploy를 할 때, 다른 Application에 대해서 신경쓸 필요없이 작업 수행이 가능하게 된다. 만약 모든 Applilcation이 하나의 Class Loader를 사용하게 된다면, 하나의 Application을 Deploy할 때마다, Class Loader가 Restruct되는 등 영향을 받을 수 있다.

- Singleton
: 이렇게 Class Loader를 따로 사용하기 때문에, Application 별로, 당연히 Singleton Pattern이 따로 적용된다. 만약 Class Loader가 전역적으로 하나만 사용되었다면, 다른 Application에 의해서, Singleton이 오작동 할 수 도 있을 것이다. (Singleton은 GoF의 Design Pattern중의 하나이다. 자세한 내용은 Design Patterns-Addison Wesley를 참고하기 바란다.)

- Namespace
: Namespace의 확장도 가능하게 되는데, webApp1.war와 webApp2.war 파일에 똑같이 index.jsp 라는 File이 있을때, WAS는 각 Class의 Name space를 Class Loader + File Name이라는 Namespace를 사용하기 때문에, 다른 Application안의 Components를, 어떻게 naming 하느냐는 것은 문제가 되지 않는다.

- Hotdeploy
: Hotdeploy는 J2EE의 중요한 feature중의 하나인데, WAS가 가동중에, Components를 Redeploy할 수 있는 기능을 Hotdeploy라고 한다. 위에서도 설명했듯이, Redeploy를 하는 기능은 Class Loader에는 없기 때문에, redeploy를 하기 위해서는 기존의 Class Loader를 Unload하는 동시에, 새로운 Class Loader를 Loading하여, Class 를 Reloading하게 된다. 이렇게 Class Loader를 나누어 놓음으로써, 효과적이고 빠르게 Redeploy가 가능하게 된다.

- Deploy
: Application의 배포역시, Application 단위로, Class Loader를 이용하기 때문에, Application 단위로 배포가 가능해진다. Class Loader를 하나만 사용했다면, 일부만 변경이되더라도 Application 전체를 Redeploy 해야 했을 것이다.
이제까지, 간단하나마, JVM Class Loader와, WebLogic Class Loader의 내용에 대해서 살펴보았다. 그러면 이 특성에 따라서 각각의 Application과 Component들을 어떤식으로 Packaging 하는가에 대해서 알아보도록 하자.

2.Packaging Component

J2EE Packaging을 하는데 있어서 가장 큰 Issue는 EJB의 Client Class (Home Interface, Remote Interface)와, Common Class들일 것이다. 이 Class들을 Deploy하는 방법이 어떤 것이 있는지, 그리고 그 장단점에 대해서 알아보도록 하자.

○ WEB-INF/classes

Servlet, JSP에서 사용하는 EJB Client Class와, Common Class를 Classes Directory에 풀어서 배포하는 방법인데, 수정과 삭제가 편하다는 장점은 있으나, Web Application 마다, Classes Directory에 배포를 해야하기 때문에, Version 관리 문제나 Sync 문제가 발생할 수 있고, File 단위로 관리하기 때문에, 번거롭다. 소규모가 Application이 아닌 경우에는 권장하기 어려운 방법

○ WEB-INF/lib

Servlet, JSP에서 사용하는 EJB Client Class와, Common Class를 jar로 묶어서, lib Directory에 위치시킬 수 있다. Jar 단위로 묶어서 Packaging하기 때문에, 관리가 간편하다는 장점이 있다. 단점은 WEB-INF/classes에 배포하는것과 같다.

○ Class files within EJB JAR

EJB에서 사용하는 Common Class와, 참고하고 있는 외부 EJB-JAR의 EJB Client Class를 하나의 jar File에 Packaging 하는 방법. 이 방법은 EJB-JAR File 단위로, 독립성이 뛰어나고 Handling하기 편하다는 장점은 있으나, 각각의 EJB-JAR에 Class들이 직접 Package 되기 때문에, 변경 사항이 있을 때마다 다시 Packaging을 해야한다.

○ Class files on system CLASSPATH

EJB Client Class와, Common Class들을 아예 System CLASSPATH에 넣어버리는 방법도 있다. 이렇게 할경우에는 CLASS를 사용하는것이 매우 간편해지기는 해지고, common class의 경우에는 중복하여 배포할 염려없이, CLASSPATH내에 있는 것만 바꾸면 되기 때문에, 일관성을 유지하기가 좋다.

그러나 그 CLASS들을 바꾸거나 할 경우에는 WAS를 Restart 해야 하는 제약 사항이 따르게 되며. Hotdeploy와 같은 기능을 사용하는 것은 불가능하게 된다.

○ jar on system CLASSPATH

바로 앞의 방법에 Class Files을 jar로 묶어서 CLASSPATH에 배포하는 방식으로, 위와 같은 단점을 가지지만, jar 단위로 묶어서 관리를 하기 때문에, 앞의 방법보다는 Class 관리가 편리하다.

○ jar in EAR

가장 일반적인 배포 방법으로 Client Class와 Common Class을 jar로 묶어서, Application EAR 안에 함께 묶어서 배포하는 방식으로, EAR 단위로 Application 관리와 배포가 가능해진다.

그러나 두개 이상의 Application이 공통된 Common Class File들을 참조하는 경우에는 각각의 EAR에 Common Class를 넣어서 Packaging 해야 하기 때문에, 이런 경우에는 일관성의 문제가 발생할 수 도 있다.

○ MANIFEST.MF

JDK1.2의 "Extension Mechanism" 이라는 이름으로 등장한 기능으로, JAR File이 다른 JAR File의 Class들을 참조할 수 있게 해주는 기능이다. 일단 사용법부터 살펴보면 /META-INF/MANIFEST.MF 라는 파일로 정의가 되며 아래와 같은 식으로 사용된다.

Manifest-Version: 1.0
Class-Path: commonclasses.jar ./account/account_ejb_client.jar
./com/bea/

이렇게 정의되어 Packaging 된 jar File 내의 Class 들은 commonclasses.jar와 ./account/account_ejb_client.jar 그리고./com/bea/ 에 있는 Class들을 사용할 수 있게 된다.

여기서 꼭 주의해야할 점은 Class-Path의 Directory 경로는 상대 경로만 지정이 가능하며, 이 상대 경로의 기준 Directory는 해당 JAR File의 Class들이 실행되는 Directory이다. 그런데, 이 실행 Directory라는 것이, WAS에 Deploy된 jar File의 경로가 아니다. WLS의 경우 해당 jar가 $WLS_HOME/config/mydomain/applications에 위치하고 있더라도, 그 Directory를 기준으로 하지 않는다는 이야기이다. 대부분의 WAS가 실행시에, 그 jar를 Compile 하거나 Cache해서 사용하는 Staging Directory에 그 class들을 위치해 놓고 수행을 하기 때문에, Staging Directory가 어디가 될지는 WAS의 종류와 환경에 따라서 다르다.

이런 이유로 MANIFEST.MF를 사용하는 경우는 EAR안에 같이 Pakaging된 JAR File 간의 Reference를 결정하는데만 사용해야 하며, 그 중에서도 Deploy Order를 정의하는데 사용된다. 즉, jar in EAR 의 경우, Common Class가 그 Class를 사용하는 EJB 보다 늦게 Deploy가 되면 Class Not Found 상태가 될 수 있기 때문에, Common Class를 먼저 Deploy 시킬 때, 그 Common Class를 사용하는 EJB의 EJB-JAR에 MANIFEST.MF를 이용하여, common class가 먼저 Loading 되게 하는데 사용을 한다.

꼭 기억해야 할 것은 위와 같은 이유로 MANIFEST.MF는 EAR안에서만 사용해야 한다는 것이다. 지금까지 Common Class와, ejb-client-class들을 Pakaging 하는 몇가지 정책에 대해서 알아 보았다. 어떤 것이 절대적으로 좋고 나쁘다는 정석은 없다. 개발 상황과, 정책에 따라서 알맞은 Pakaging 정책을 선택하는 것이 올바른 길일 것이다. 단. Packaing 정책을 결정하지 않고, 개발을 진행하다가는 추후에 낭패를 볼 수 있으니, Pakaging 전략을 수립한 후에, 개발을 진행하도록 하자.

○ APP-INF/lib or APP-INF/classes (WLS 8.1 이상)

WLS 8.1부터 새로 등장한 방법으로, common class들을 APP-INF/classes나, lib Directory에 배치하면, 그 EAR안에서 자유롭게 사용할 수 있게 된다

NOTE!
좀 더 효율적인 Packaging 전략 수립을 위해서는 Component간의 Dependency와 Packaging 구조를 파악하는 것이 중요한데, 이는 UML을 이용한 OOAD(Objected Oriented Analysis and Design) 단계에서 Class 간의 Dependency Diagram을 통해서 파악하고, 이를 Deployment Diagram을 통해서 형상화 하면 좀더 논리적이고 체계적으로 Packaging 전략을 수립하는 것이 가능하다.

※ Call by reference and Call by value.
잘 알고 있겠지만, Java의 Call 방식에는 Call by reference와, Call by value 두가지 방법이 있다. 당연히 Call by reference가 속도나 효율면에서는 뛰어나겠지만, EJB와 같은 Remote Call의 경우에는 사용되는 Object나, Call Method의 인자 전달을 Call by value를 사용한다.

WLS 에서는 같은 EAR안에 Packaging을 할 경우에는 WLS가 RMI Call을 Optimize하여, Call by Reference로 하도록 조정해주고, Local Interface를 사용할 경우에도, Call by Refrerence를 사용하도록 한다.

이런 이유로, 같은 EJB를 어떤식으로 Packaging하느냐에 따라서도 Performance 차이가 날 수 있다는것을 참고하도록 하자.

3. EJB Packaging Order

지금까지는 Application이 어떻게 Packaging 되는지, Packaging 된 Class들이 어떤 방식으로 Loading 되는지 알아보았다. 그럼 WebLogic Server에서, 어떤 과정을 거쳐서, EJB를 Packaging 하여 war, jar, EAR등을 만들어내는지에 대해서 알아보도록 하자

○ MANIFEST.MF

1) Develop EJB Component
2) Compile EJB Component : 개발한 EJB를 class로 Compile 한다.
3) Define EJB Deployment Descriptor

WebLogic에서는 3개의 Deployment Descriptor를 필요로 한다.

- ejb-jar.xml
- weblogic-ejb-jar.xml
- weblogic-cmp-rdbms-jar.xml (optional, for CMP only)

EJB의 Deployment Descriptor를 만들어야 되는데, 이 부분은 WebLogic에서 어느 정도 자동화가 가능하다. EJB Class가 있는 Directory에서 다음 명령어를 이용하면, Deployment Descriptor (ejb-jar.xml weblogic-xxx.xml) File을 자동으로 생성해 준다.

WLS6.1
(EJB 1.1) java weblogic.ant.taskdefs.ejb.DDInit [dir]
(EJB 2.0) java weblogic.ant.taskdefs.ejb20.DDInit [dir]
(Web App) java weblogic.ant.taskdefs.war.DDInit [dir]
(App) java weblogic.ant.taskdefs.ear.DDInit [dir]

WLS 7.0
(EJB) java weblogic.marathon.ddinit.EJBInit [dir]
(App) java weblogic.marathon.ddinit.EarInit [dir]
(Web App) java weblogic.marathon.ddinit.WebInit [dir]

이를 통해서 생성된 EJB DD들은 완전한 것이 아니기 때문에, 직접 Editor를 통해서 수정하도록 하자. 아래 그림은 각각의 EJB Deployment Descriptor가 어떻게 System과 Mapping이 되는지를 나타내 주는 그림이다.

 

4) packaging EJB to jar file : 이렇게 개발된 EJB Class File들과, Deployment Descriptor를 jar Utility를 이용해서 jar File로 Packaging 한다.
5) generate EJB stub (* important !!) : 4)단계까지는 대부분의 사용자가 잘 진행을 하지만, 시중의 많은 서적이나, 초보 가이드 문서에 빠져있는 부분이 EJB Stub을 만드는 부분이다.



우리가 Coding하는 EJB 부분은 EJB의 Logic부분이다. EJB는 분산 객체이기 때문에, 아랫단에서 Netowrk 환경을 위한 RMI 등의 통신 Mechanism을 제공하는데, 이 통신 Mechanism에 해당하는 부분이 EJB의 Stub Class들이다. 요즘의 WAS들은 이 Stub Class들을 EJB Deploy과정에서 자동으로 생성해주는 경우가 많은데, 이 과정은 Server에 Upload되는 순간에, EJB의 내용을 분석하여, Stub의 Java Source File을 생성하고, javac Compiler를 invoke하여, Stub Class를 Generation 하게 된다. 이 기능은 개발시에 매우 편리하니, 개발 과정에서 사용하도록 하자.

그러나 운영시에는 Deploy하는 과정에 많은 EJB stub을 만들고 Compile 하는데 많은 Resource가 소요된다. 결과적으로, 한꺼번에 많은 EJB를 Deploy할때는 이 Stub을 생성하는 과정에서 동시에 많은 Resource가 사용되서 System이 느려지거나, Boot Up 시간에 영향을 주는 경우가 많다.

이런 이유로, EJB를 Server에 Deploy하기 위해서, EJB Stub을 미리 생성해서 Packaging하여 Deploy 하는 것이 좋다. 다음과 같은 방법으로, EJB Stub을 포함한 jar File을 생성할 수 있다.

% java weblogic.ejbc [ejb-jar-file-name] [result-file-name]
example)
% java weblogic.ejbc account_manager.jar account_manager_stub.jar

여기까지 진행하면, Deploy를 하기 위한 하나의 완벽한 ejb-jar File이 작성된 것이다.

6) packaing EJBs into ear files

앞에서 작성한 ejb-jar File과 War File들을 적정한 Directory에 배치하고, META-INF/application.xml File을 작성한 후 jar Utility를 이용하여 EAR로 생성하면 최종 Deploy를 위한 준비가 끝난 것이다.

○ Specifying ejb-client.jar

EJB를 Client에서 사용하려면 위에서 설명하였듯이, EJB Client Class들이 필요하다.

EJB Client Class들은 EJB Home Interface, Remote Interface, Primary Class Interface나 기타 인자가 되는 Class들로 구성이 되는데, 이 Class들만 묶어서, 해당 EJB를 사용하기 위한 jar File로 구성하게 된다. (※ 이때, EJB Implementation Class들과, Stub Class들을 같이 묶는 경우가 있는데, 이는 Deploy 방법이나 CLASSPATH 설정등에 따라서 심각한 문제를 발생시킬 수 있으니, 절대로 같이 Packaging하지 말자.)

이 File들을 일일이 골라내서 Packaging 하는 것도 여간 번거로운 작업이 아닐 수 없다. 이것을 좀 더 편리하게 하기 위해서, J2EE Spec에서는 자동으로 ejb-client.jar Class를 생성해주는 기능을 제공하는데, 간단하게 ejb-jar.xml을 수정하고, java weblogic.ejbc xxx를 실행해주면 된다.

구체적인 순서는 다음과 같다.

- ejb-jar.xml에 ejb-client-class.jar 라는 Eliment를 추가한다.
- ejb-jar 파일을 java weblogic.ejbc [ejb-jar-file-name] [result-file-name] 를 실행하면, 해당 Directory에 ejb-client-class.jar라는 Fule 이름으로, client Class만 추출되어진 jar File이 생성된다.

이렇게 생성된 jar File들은, Servlet/JSP에서 사용할 경우 WEB-INF/lib 에 위치하거나, Client Application의 classpath 내에 적용되어 사용된다.

○ Deploying Pinned EJB

특히 Cluster에 EJB를 Deploy할 때는 특별한 주의가 필요한데, Cluster의 경우에는 EJB를 하나의 Server에만 Deploy하고, Targeting을 통하여, Cluster내의 다른 Server에, EJB를 배포할 수 있다.

이경우, EJBC를 거치지 않은 EJB의 경우에는 Upload한 Server의 경우에는 자동으로 EJBC를 실행하여, stub을 생성하지만, Targeting에 의해 EJB가 복제된 다른 Server의 경우에는 stub이 없는 File이 복제 되기 때문에, Client에서 그 EJB를 호출할 경우, RMI Layer에서 Assertion Error가 발생하게 된다.

○ Ant utility

지금까지 EJB를 배포하기 위한 Package를 생성하는 순서에 대해서 살펴보았다. 과정이 길고 복잡하기 때문에, 개발도중 매번 일일이 실행하기에는 매우 복잡하기 때문에, J2EE에서는 예전 Unix 시절의 Make와 같은 Utility를 제공한다. Ant라는 이름의 Utility로, build.xml이라는 Scripts를 만들어서 위의 과정을 자동화할 수 있다. 거의 EJB 개발에서는 표준으로 사용하고 있는 Utility이니 한번 Check해 놓도록 하자.

좀더 자세한 정보는 http://ant.apache.org/ 를 참고하시 바란다.

4. EJB deploy in WebLogic Server

이렇게 만들어진 Archieve file들(war,ear,jar)을 WebLogic에서 EJB를 Deploy하는 방법은 크게 3가지 방법이 있다.

   - Console Deploy
   - Command line deploy
   - Auto deploy

○ Console deploy

WebLogic Console을 이용하여, Web Browser에서 Deploy 하는 방법이다. 간단한 방법이므로 본 문서에서는 따로 설명하지 않는다. http://edocs.bea.com 의 WLS deploy 문서를 참고하기 바란다.

○ Command line deploy

Web Browser를 사용할 수 없는 command Line 환경에서 사용할 수 있는 방법이다.
%java weblogic.deploy ?port port_number ?host host_name deploy password name source example)
%java weblogic.deploy ?port 7001 ?host localhost deploy weblogicpassword CMP_example c:\weblogic\CMP_example\
%java weblogic.deploy ?port 7001 ?host localhost deploy weblogicpassword bean_jar c:\weblogic\bean.jar

source 부분에는 EJB Beans의 jar File의 Full 경로가 들어가거나 또는 Directory 명이 들어간다.

○ Auto deploy

WebLogic의 $WL_HOME/config/$DOMAIN_NAME/applications (WLS6.1 기준) Directory에 jar File이나, EJB Directory를 복사해놓으면, WebLogic이 Boot Up시에, 자동으로 Deploy되거나 또는 그 EJB의 내용이 변경되었을때, 자동으로 Redeploy를 한다.

Boot Up시에 Deploy되는 기능은 언제나 사용이 가능하지만, WebLogic 기동중에, ejb-jar File을 바꿔서 Redeploy하는 기능은, WebLogic을 Development Mode로 부팅했을 때만 가능하다. Development Mode로 WebLogic을 Booting 하는 방법은 startWebLogic.sh 에서 java Option에서, Dweblogic.Productiob ModeEnabled = false 로 해주면 Development로 Booting이 된다.

○ Partial Upgrade (Only WLS 8.1 이상)

WLS8.1에서는 Class Loader Model이 변경되어, 좀 더 향상된 Deploy가 가능하다. EJB는 Interface를 통해서 호출이 되기때문에, Interface가 변경되지 않은 상태에서, Implemtation Class 하나만 변경하여 Redeploy하는 기능이 추가되었다.

이는 예전 버전에서는 각각의 Application 단위로, EJB Class를 Loading하였다. (JAR File의 경우, 하나의 Application Class Loader가, JAR 안의 모든 EJB를 Loadinig 했고, EAR의 경우에도, 하나의 Application Class Loader가 모든 EJB Class를 Loading 했었다.) 그러나, 8.1 에서부터는 아래 그림과 같이 각각의 Application Class Loader아래에, 각각의 EJB Implemetation Class마다 별도의 Class Loader가 가동되게 됨으로써 가능해진 기능이다.

각각의 EJB Implementation Class를 redeploy하기 위해서는 "java weblogic.Deployer ?adminurl url ?user user ?password password ?name myapp ?redeploy myejb/foo.class" 을 해주게 되면, myapp application의 myejb jar Pakage에서 foo.class라는 EJB implementation file만 redeploy를 해준다.


여러개의 File들을 한꺼번에 Update 할 수 도 있는데, 이는, redeploy Option 뒤에, 다음과 같이 파일명들을 정의해주면 된다.

"java weblogic.Deployer ?adminurl url ?user user ?password password ?name myapp ?redeploy myejb/foo.class mywar anotherejb"

위의 명령의 경우에는 myapp의 myejb jar의 foo.class, 그리고 mywar.war Web Application과 anotherejb EJB Pakage를 Redeploy를 해준다. 이때, 이 3개의 File로 인해서 Redeploy를 해줘야 하는 Dependency 관계가 있는 다른 Component 들도 자동으로 Redeploy를 해주게 된다.

5. Programming Tip

이번 기사를 정리하는 기분으로, 한가지 Class Loader의 Tip을 소개한다. 해당 Class가 어느 Class Loader를 통해서 Loading 됐는지를 쉽게 알 수가 있다.

해당 CLASS에 다음과 같은 Code를 삽입하면 된다.

   ClassLoader loader = null;
   loader = this.getClass().getClassLoader();
   System.out.println("This class is :"+this.getClass().getName());
   while(loader != null){
      System.out.println(loader.getClass().getName());
      loader = loader.getParent();
   }//while

(EJB Class 안에 넣고 이 Code를 수행했을 때 수행 결과는 다음과 같다. WLS6.1 기준.)

   This class is :com.bea.examples.simpleEJB.AccountManagerEJB_fsrjh9_Impl
   weblogic.utils.classloaders.GenericClassLoader
   sun.misc.Launcher$AppClassLoader
   sun.misc.Launcher$ExtClassLoader

[참고 자료]
http://java.sun.com/docs/books/tutorial/ext/basics/load.html
http://e-docs.bea.com/wls/docs61/ejb/EJB_deployover.html#1011066
http://e-docs.bea.com/wls/docs81/programming/classloading.html#1083313
http://dev2dev.bea.com/articles/musser.jsp 
http://java.sun.com/docs/books/tutorial/jar/basics/manifest.html

저작자 표시 비영리 변경 금지
Creative Commons License

'Programming > Java' 카테고리의 다른 글

Java VM Core Dump 분석  (0) 2010/02/17
How to deploy EJB component  (0) 2007/10/11
EJB(Enterprise Java Beans)  (0) 2007/09/28
Posted by BLUEDAY™