WAR 모듈의 EJB 컨텐츠
이 주제를 사용하여 웹 애플리케이션 아카이브(WAR) 모듈의 EJB(Enterprise JavaBeans) 컨텐츠에 대한 패키지 요구사항을 이해합니다.
지원되는 EJB 컨텐츠
명시적으로 언급된 제한사항을 제외하고 EJB JAR(Java™ archive) 모듈 내에 패키지된 Bean에 대해 지원되는 EJB 함수는 WAR 모듈에 패키지된 Bean에 대해서도 지원됩니다. WAR 모듈에 패키지된 Bean은 EJB JAR 모듈에 패키지된 Bean과 동일한 동작을 가질 수 있습니다.
EJB 3.x Bean의 모든 유형은 WAR 모듈, 2.x, 1.x 세션 Bean에서 지원됩니다. 전체 세부사항에 대해서는 EJB 3.1 스펙을 참조하십시오.
패키징 메커니즘
WAR 모듈의 EJB 컨텐츠를 패키징하기 위한 규칙은 JAR 모듈의 EJB 컨텐츠 패키징을 위한 규칙과는 다릅니다.
- WEB-INF/classes 디렉토리 구조로 느슨하게
- WEB-INF/lib 디렉토리에 있는 JAR 파일 내
예를 들어, WEB-INF/classes/com/foo/MyBean.class 위치에서 WAR 모듈에 Bean 클래스 com.foo.MyBean을 느슨하게 배치할 수 있습니다.
이 Bean 클래스를 myJar.jar 파일에 배치할 수도 있으며 이는 WEB-INF/lib/myJar.jar 위치입니다.
WAR 모듈은 WEB-INF/classes 디렉토리 구조로 느슨하게 배치된 일부 Bean 코드를 포함할 수 있으며 WEB-INF/lib 디렉토리의 JAR 파일 내에 다른 Bean 코드를 포함할 수도 있습니다. WAR 모듈은 모든 Bean 코드를 WEB-INF/classes 디렉토리 구조에 포함하고 WEB-INF/lib 디렉토리에는 아무것도 포함하지 않거나 모든 Bean 코드를 WEB-INF/lib 디렉토리의 JAR 파일에 포함하고 WEB-INF/classes에는 아무것도 포함하지 않을 수도 있습니다.
WEB-INF/lib 디렉토리에 여러 개의 JAR 파일을 포함하고 이들 모두가 Bean 코드를 포함하는 것도 유효합니다.
동일한 Bean 클래스가 WEB-INF/classes 디렉토리 구조에 느슨하게 배치되고 WEB-INF/lib 디렉토리의 JAR 파일에도 배치되는 경우, WEB-INF/classes 디렉토리 구조에 느슨하게 배치된 클래스의 인스턴스가 로드되며 WEB-INF/lib 디렉토리의 JAR 파일에 배치된 인스턴스는 무시됩니다.
동일한 Bean 클래스가 WEB-INF/lib 디렉토리에서 두 개의 다른 JAR 파일에 배치되는 경우, 로드되는 클래스 인스턴스와 무시되는 클래스 인스턴스를 알지 못합니다. 런타임 시에 서버는 임의로 하나의 클래스 인스턴스를 선택하여 로드하고 다른 클래스 인스턴스는 무시합니다.
- WEB-INF/classes/META-INF/persistence.xml
- WEB-INF/lib/MyEntity.jar
IWAE0068W 라이브러리 아카이브
foo.jar 파일에 있는 EJB 배치 디스크립터 META-INF/ejb-jar.xml은 무시됩니다. 제품은
라이브러리 아카이브에서 META-INF/ejb-jar.xml 배치 디스크립터를 처리하지 않습니다. META-INF/ejb-jar.xml
배치 디스크립터를 라이브러리 아카이브에서 WAR 모듈의 WEB-INF 디렉토리로 이동하십시오.
EJB 컨텐츠를 포함하려면 WAR 모듈은 버전 2.5 이상이어야 합니다. 버전 2.4 이전의 WAR 모듈에 있는 EJB 컨텐츠는 무시됩니다.

WAR 파일로 패키지되는 엔터프라이즈 Bean의 기술적인 차이점
다음 목록은 WAR 모듈로 패키지되는 Bean과 EJB JAR 모듈로 패키지되는 Bean의 주요 기술적인 차이점을 포함합니다.
- 공유 컴포넌트 네임스페이스
WAR 모듈의 모든 컴포넌트는 한 개의 컴포넌트 네임스페이스를 공유합니다. 즉, 각 EJB 컴포넌트는 한 개의 컴포넌트 네임스페이스를 WAR 파일의 다른 모든 EJB 컴포넌트 및 서블릿과 같은 모든 비EJB 컴포넌트와 공유합니다. 이와 반대로 EJB JAR 모듈로 패키지되는 EJB 컴포넌트는 자체적으로 개인용 컴포넌트 네임스페이스를 포함하며 이는 다른 어떤 컴포넌트와도 공유하지 않습니다.
공유 컴포넌트 네임스페이스는 중요한 영향을 줍니다. 우선, 한 개의 컴포넌트(EJB 또는 비EJB)가 참조를 선언하고 다른 컴포넌트는 해당 참조에 대해 컴포넌트 네임스페이스를 검색할 수 있습니다. 두 번째로 임의 컴포넌트가 선언한 참조는 다른 컴포넌트가 선언한 참조와 충돌할 수도 있습니다. 이와 반대로 EJB JAR 모듈로 패키지된 EJB 패키지는 컴포넌트 네임스페이스에서 다른 EJB 또는 비EJB 컴포넌트가 선언한 참조를 검색할 수 없으며 EJB가 선언한 참조가 이름이 동일하더라도 다른 컴포넌트가 선언한 참조와 컴포넌트 네임스페이스에서 충돌할 수 없습니다.
공유 네임스페이스를 사용하는 경우, 동일한 참조가 여러 번 선언될 수 있으며 이는 해당 참조 선언이 다른 선언과 충돌하지 않는 경우입니다. 참조 선언이 충돌하지 않으면 서버는 참조가 정확하게 한 번만 선언된 것처럼 작동합니다.
참조 선언이 충돌하면 오류 메시지가 생성되고 애플리케이션이 시작되지 않습니다. 경고 메시지가 충돌하는 각 참조에 대해 생성됩니다. 경고 메시지는 충돌한 참조 이름과 해당 참조에 지정된 다중 값을 표시합니다. 모든 경고 메시지가 생성된 후에 예외로 처리됩니다.
- EJB 디스크립터 파일 위치
ejb-jar.xml 배치 디스크립터 파일과 다른 모든 디스크립터 파일은 WAR의 WEB-INF 디렉토리에 있어야 합니다. WEB-INF/lib 디렉토리에서 JAR 파일의 META-INF 디렉토리를 포함하여 WAR 내에 있는 모든 EJB 디스크립터 파일 인스턴스는 무시됩니다.
- 어노테이션 스캔 여부 판별
어노테이션 스캔 여부 판별 규칙은 EJB JAR과 WAR 모듈에 대해 다릅니다. 전체 규칙 세트는 EJB 3.x 모듈 패키징 개요 주제를 참조하십시오.
- 클래스 로드 및 가시성
WAR 모듈로 패키지되는 EJB 클래스에 대한 대부분의 공통 사용 패턴은 동일한 모듈 내에 패키지된 웹 컴포넌트에서의 로컬 메소드 호출입니다. 그렇지만 이런 EJB 클래스는 원격 메소드 호출이나 다른 모듈의 클라이언트로도 액세스할 수 있습니다. 이런 경우, WAR 모듈에 패키지된 EJB 클래스의 가시성 규칙을 이해하는 것이 중요합니다. 가시성 규칙은 JAR 모듈에 패키지된 EJB 클래스에 비교하면 다릅니다.
원격 EJB 메소드 호출의 경우, EJB 클래스를 WAR 모듈로 패키지하여 도입된 가시성의 차이는 없습니다. EJB는 글로벌 네임스페이스로 바인드되고 다른 모듈의 컴포넌트에서 검색 또는 이런 컴포넌트로 주입될 수 있습니다. 원격 클라이언트는 적절한 스텁 클래스로 메소드 호출을 수행해야 합니다. 스텁 클래스 생성은 이 주제의 "스텁 생성" 절에서 설명됩니다.
다른 모듈의 컴포넌트에서의 로컬 EJB 메소드 호출인 경우, EJB가 WAR 모듈로 패키지되기 때문에 가시성 차이가 있습니다. 이 가시성 차이는 고려해야 하는 클래스 로더 내포가 있기 때문에 발생합니다.
전체 애플리케이션용으로 모든 EJB JAR 모듈에 패키지되는 컨텐츠는 단일 애플리케이션 클래스 로더 인스턴스로 로드됩니다.
이와 반대로 WAR 모듈에 패키지되는 모든 컨텐츠는 해당 WAR 모듈에만 적용되는 클래스 로더 인스턴스에 로드됩니다. 모든 EJB JAR 컨텐츠 로드에 사용되는 한 개의 애플리케이션 클래스 로더 인스턴스가 WAR 컨텐츠 로드에 사용되는 각 클래스 로더 인스턴스의 상위입니다.
클래스의 가시성은 이를 로드한 클래스 로더 인스턴스의 영향을 받습니다. 클래스 로더 인스턴스에게는 자체적으로 로드되었거나 상위 클래스 로더가 로드한 클래스가 표시됩니다. 그렇지만 클래스 로더는 자체 또는 해당 상위 중 하나가 아닌 클래스 로더에 로드된 클래스는 볼 수 없습니다.
그 결과, WAR 모듈에 특정한 클래스 로더가 로드한 클래스는 EJB JAR 모듈의 클래스는 볼 수 있지만 다른 WAR 모듈의 클래스는 볼 수 없습니다. EJB JAR 모듈의 클래스는 다른 WAR 모듈의 클래스를 볼 수 없습니다. 예를 들어, EJB JAR 모듈 ejb3.jar에 패키지된 EJB 컨텐츠가 있고 ejb1.jar 파일과 ejb2.jar 파일에 패키지된 EJB 컨텐츠도 있는 경우, 다음과 같습니다.- ejb1.jar 파일과 ejb2.jar 파일이 EJB JAR 모듈로 설치된 경우, ejb1.jar 파일, ejb2.jar 파일, ejb3.jar 파일 내의 컨텐츠는 동일한 클래스 로더 인스턴스에 로드되며 이는 애플리케이션의 다른 모든 EJB JAR 모듈 로드에도 사용됩니다. 이 경우, 이 세 JAR 파일 모두의 클래스는 모두 동일한 클래스 로더 인스턴스로 로드되었기 때문에 서로를 볼 수 있습니다.
- ejb1.jar 파일과 ejb2.jar 파일 모두 WAR 파일의 WEB-INF/lib 디렉토리에 패키지된 경우, ejb1.jar 파일과 ejb2.jar 파일의 컨텐츠는 한 개의 클래스 로더 인스턴스로 로드됩니다. 그렇지만 이 클래스 로더는 ejb3.jar 파일 및 애플리케이션의 다른 모든 EJB JAR의 컨텐츠 로드에 사용되는 것과 동일한 클래스 로더가 아닙니다. 이런 경우, ejb1.jar 파일과 ejb2.jar 파일의 클래스는 서로를 볼 수 있으며 ejb3.jar 파일의 클래스도 볼 수 있습니다. ejb3.jar 파일의 클래스는 ejb1.jar 파일 또는 ejb2.jar 파일의 클래스는 볼 수 없습니다.
- ejb1.jar 파일이 firstWar.war 파일의 WEB-INF/lib 디렉토리에 패키지되고 ejb2.jar 파일이 secondWar.war 파일의 WEB-INF/lib 디렉토리에 패키지되는 경우, ejb1.jar 파일의 컨텐츠는 처음 클래스 로더 인스턴스에 로드되고 ejb2.jar 파일의 컨텐츠는 두 번째 클래스 로더 인스턴스에 로드되며 ejb3.jar 파일 및 애플리케이션의 다른 모든 EJB JAR 컨텐츠는 세 번째 클래스 로더 인스턴스에 로드됩니다. 이 경우, ejb1.jar 파일 및 ejb2.jar 파일의 클래스는 서로를 볼 수는 없지만 ejb3.jar 파일의 클래스는 볼 수 있습니다. ejb3.jar 파일의 클래스는 ejb1.jar 파일이나 ejb2.jar 파일의 클래스를 볼 수 없습니다.
이런 클래스 로드 복잡성을 방지하는 하나의 전략은 EJB 인터페이스 클래스를 공유 라이브러리에 패키지하는 것입니다.우수 사례: 동일한 애플리케이션에 동일한 클래스, EJB JAR 모듈 및 WAR 모듈 둘 다를 패키지하지 마십시오. 동일한 애플리케이션 내에서 여러 위치에 동일한 클래스를 패키지하면 로드되어 런타임에서 사용되는 클래스 인스턴스에 대한 혼동을 초래할 수 있습니다. 두 .class 파일이 다른 클래스 버전을 나타내는 경우에는 이 구분이 중요할 수 있습니다. 이런 시나리오를 방지하려면 .class 파일을 한 위치에만 패키지하거나 클래스의 패키지 구조를 변경하여 WAR 모듈에 패키지된 클래스의 완전한 이름이 EJB JAR 모듈에 패키지된 클래스의 완전한 이름과 다르도록 하십시오. bprac
- 애플리케이션 프로파일 확장
애플리케이션 프로파일 확장은 WAR 모듈에 패키지된 EJB 클래스에 대해서는 지원되지 않습니다.
스텁 생성
EJB 메소드의 원격 액세스를 위해서는 클라이언트 측 스텁 클래스를 사용해야 합니다. 대부분의 클라이언트 환경의 경우 제품 런타임은 자동으로 필수 스텁 클래스를 생성합니다. 한 가지 예외는 씬 클라이언트 환경입니다. 씬 클라이언트의 경우, 스텁 클래스는 수동으로 생성되어 클라이언트와 패키지되어야 합니다.
createEJBStubs 도구를 사용하여 EJB 버전에 상관없이 EJB 컨텐츠가 WAR 모듈에 패키지될 때 스텁을 생성하십시오.
자세한 정보는 스텁 작성 명령 주제를 참조하십시오.

WAR 모듈의 EJB 2.x 및 1.x 컨텐츠
전체 엔티티 Bean을 제외하고 EJB 2.x 및 1.x 컨텐츠가 WAR 모듈에서 지원됩니다.
WAR 파일에 패키지된 2.x 또는 1.x 모듈의 경우 WAR 모듈의 WEB-INF 디렉토리에 버전 2.x 또는 1.x의 ejb-jar.xml 배치 디스크립터가 필요합니다. XMI 바인딩과 확장 파일이 있는 경우에는 해당 바인딩과 파일도 WAR 모듈의 WEB-INF 디렉토리에 패키지해야 합니다.
2.x 또는 1.x 코딩 스타일에 따라 구현하는 세션 Bean과 메시지 구동 Bean은 WAR 모듈 내에 패키지할 수 있습니다.
BMP(Bean Managed Persistence) 및 CMP(Container Managed Persistence) 엔티티 Bean 모두 WAR 모듈에서 지원되지 않습니다.
애플리케이션 프로파일링 및 액세스 목적 서비스는 WAR 모듈에서 지원되지 않습니다. WAR 모듈에 있는 세션 Bean은 애플리케이션 프로파일링 태스크에 액세스할 수 없습니다.
3.x 코딩 스타일 및 2.x와 1.x 코딩 스타일에 따라 구현하는 EJB 컨텐츠는 한 개의 WAR 모듈로 같이 패키지할 수 있습니다. 그렇지만 이런 경우 XMI 버전이 아니라 파일의 XML 버전으로 모든 바인딩 및 확장 정보를 선언해야 합니다.
기존 EJB 컨텐츠를 EJB JAR 모듈에서 WAR 모듈로 이동
한 가지 방법은 WAR 파일의 WEB-INF/lib 디렉토리에 기존 EJB JAR 파일을 추가하는 것입니다. 그런 다음 JAR 파일의 META-INF 디렉토리에서 디스크립터 파일을 제거하고 이를 WAR 파일의 WEB-INF 디렉토리에 배치하십시오.
두 번째 방법은 WAR 모듈의 WEB-INF/classes 디렉토리의 올바른 위치에 EJB JAR 파일의 클래스 파일을 추가하는 것입니다. 그런 다음, JAR 파일의 META-INF 디렉토리에서 디스크립터 파일을 제거하고 이를 WAR 파일의 WEB-INF 디렉토리에 배치하십시오.
여러 개의 EJB JAR 모듈이 한 개의 WAR 모듈로 이동하는 경우, EJB JAR 모듈의 META-INF 디렉토리에 이전에 있는 각 디스크립터 파일의 컨텐츠를 현재 WAR 파일의 WEB-INF 디렉토리에 배치된 디스크립터 파일의 단일 버전으로 병합해야 합니다. 병합되는 디스크립터 파일의 예에는 다음이 포함되지만 이로 국한되지는 않습니다. ejb-jar.xml, ibm-ejb-jar-bnd.xml, ibm-ejb-jar-ext.xml, ibm-ejb-jar-ext-pme.xml.
WAR 모듈, EJB와 비EJB 모두의 다양한 컴포넌트로 선언되는 참조를 검사하여 서로 충돌하지 않는지 확인해야 하며 이는 WAR 모듈의 전체가 한 개의 컴포넌트 네임스페이스를 공유하기 때문입니다.
EJB JAR 모듈에서 여러 위치의 WAR 모듈로 이동한 바인딩과 확장 XMI 파일은 META-INF/ejb-jar.xml에 대한 참조를 제거하고 이를 WEB-INF/ejb-jar.xml로 대체하기 위해 수정해야 합니다.
EJB JAR 모듈에서는 지원되지만 WAR 모듈에서는 지원되지 않는 EJB 함수
- BMP 및 CMP 엔티티 Bean
- EJB 3.1 이전 스타일 시작 Bean주의: EJB 3.1로 정의된 싱글톤 시작 Bean은 지원됩니다.
CWMDF0025E: Entity beans in EJB web application archive (WAR) modules are not allowed,
per the EJB 3.1 specification.
WSVR0039E: Unable to start EJB JAR, foo.war: Entity beans in EJB web application archive
(WAR) modules are not allowed, per the EJB 3.1 specification. The foo bean in the foo.war module
must be moved to a stand-alone EJB module. Examine the log to see a full list of invalid entity
beans in a WAR module.