This topic describes application packaging when you use EJB 3.0 beans.
Packaging applications that use EJB 3.0 beans is similar to the assembly requirements for Java 2 Platform, Enterprise Edition (J2EE) 1.4 applications: components are packaged into modules, and modules are packaged into application enterprise archive (EAR) files. The components and modules both have describing metadata provided in an Extensible Markup Language (XML) deployment descriptor. The EJB 3.0 specification supports an additional method to describing metadata and for packaging persistence units.
EJB modules without deployment descriptors
You can package EJB modules without a deployment descriptor if you are using EJB 3.0 beans. To do this, you must create a JAR file with metadata in an annotation which is located in the EJB component. EJB 3.0 beans do not need an entry in the ejb-jar.xml file for metadata that you have defined through annotations.
When you use annotations the module is scanned at runtime for the deployment descriptor metadata that is contained in the component class files.
EJB modules with deployment descriptors
You can continue to use EJB modules with deployment descriptors in the feature pack. Modules with deployment descriptors can support any EJB specification version level, including EJB 3.0, but generally these descriptors should reflect the implementation requirements of the components in the module.
An EJB module can have an EJB 2.1-, or earlier, style deployment descriptor, or an EJB 3.0-style deployment descriptor.
For EJB 2.1-style deployment descriptors, it is assumed that the deployment descriptor contains the full metadata for the module, and no additional scanning of annotation metadata occurs.
The EJB container annotation scanning is performed on EJB modules that either have no deployment descriptor or have an ejb-jar.xml deployment descriptor at the EJB 3.0 schema level. In other words, the scan finds the annotation and its describing metadata.
Persistence units
Persistence units, including the persistence.xml file and the classes associated with it, can be packaged in the module for which they are required. They can also be packaged in the separate utility JAR file that is packaged in the EAR file with its dependent module.
Application packaging
Modules that utilize the EJB 3.0 specification should be packaged in an EAR file with a J2EE 1.4 deployment descriptor so that legacy application security management can be used.
You can mix EJB 2.x and earlier beans with EJB 3.0 beans in the same application, but you do need to separate EJB 2.x and earlier beans from EJB 3.0 beans so that they are not in the same modules. EJB 3.0 beans are not recognized in modules that contain EJB 2.1-style, or earlier, deployment descriptors.
AutoLink provides the ability to automatically resolve EJB references to components contained with an EAR file, without having to specify a JNDI binding name. This simplifies application deployment with large numbers of beans and references if they are unique and unambiguous. Restriction: AutoLink should not be used for references to components deployed on a cluster.
JPA packaging
It is recommend that persistence units be packaged in separate JAR files to make them more accessible and reusable. These can be tested outside the container, with or without actual database persistence occurring. Persistence units can be included in standalone applications or into EAR files as utility JAR files. Because of the variety of use cases and potential performance issues when scanning large quantities of classes, it is recommended that the persistence unit defines the classes of the persistence units.
Session facades used for persistence scenario
A common pattern is to use session facades for persistence. This release supports the use of session bean facades driving JPA. The EntityManager interface is not thread safe, therefore, servlets should never inject @PersistenceContext. Servlets must either use the facade pattern or use an EntityManagerFactory instance to create an EntityManager on each request.
It is recommended that JPA persistence units be defined in a separate JAR file, apart from the session bean facades. Not only is this a best practice that gives greater flexibility in sharing, it also avoids problems mixing JPA and non-JPA annotated classes.
Manifest-Version: 1.0 Class-Path: TradeInfo.jarThe session facade in the EJB3Trade.jar file refers to JPA entity classes and persistence units in the TradeInfo.jar file. The Web application defined in the TradeWeb.war file can do the same to work with the JPA entity objects as Data Transfer Objects flowing between the Web and EJB container tiers.
Cross-tier and cross version session bean reference scenario
There are several ways to define and use references to EJB 3.0 session beans. For EJB 3.0 session to session, the @EJB injection target can be used. For cross-tier, for example, Web application to EJB 3.0 session, or cross-version, for example, EJB 2.1 session to EJB 3.0 session, an XML deployment descriptor reference can be used to define ejb-refs and ejb-local-refs. There are two variations of these, depending on whether an EJB 3.0 business interface is referred to, or a pre-EJB 3.0 component-style interface that also defines an EJBLocalHome is referred to. Web applications and client applications can also utilize @EJB if the component being referenced can be resolved using autolink.
<ejb-local-ref id="EJBLocalRef_1154112538064"> <description>com.ibm.persistence.ejb3.order.facadecom.ibm.persistence.ejb3.order.facade</description> <ejb-ref-name>ejb/OrderEJB</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <local-home></local-home> <local>com.ibm.persistence.ejb3.order.facade.OrderProcessor</local> </ejb-local-ref>The client code also needs to be adjusted to do the appropriate casting for the object being looked up. In this case, the business interface instead of the home interface:
try { InitialContext ctx = new InitialContext(); orderProcessor = (OrderProcessor)ctx.lookup("java:comp/env/ejb/OrderEJB"); } catch(Exception e) { e.printStackTrace(System.out); throw new ServletException(e); }