August 8, 2020
Hot Topics:

Packaging EJB 3 Applications

  • By Debu Panda, Reza Rahman, Derek Lane
  • Send Email »
  • More Articles »

Packaging session and message-driven beans

A car manufacturer has to assemble all essential parts of a car before it can run. As an EJB developer you build core classes that make your application, and you have to assemble them as an EJB-JAR and deploy them into your application server before your customers can execute the application.

Throughout this article we have used annotations and avoided deployment descriptors. The EJB deployment descriptor (ejb-jar.xml) describes the contents of an EJB-JAR, such as beans, interceptors, the resource they use, security, transaction settings, and so forth. For every annotation we have discussed in this article there is an element in the descriptor. Deployment descriptors can be used to override settings in metadata annotations. Let's now uncover the elements of ejb-jar.xml and explain how you can define default interceptors. We'll conclude this section with a discussion on vendor-specific descriptors and annotations.

Packaging EJB-JAR

Session beans and MDBs can be packaged in a Java standard JAR file as defined in the Java Archive specification at http://java.sun.com/j2se/1.5.0/docs/guide/jar/. To create an EJB-JAR file to package your EJB components, you have to compile your EJB classes and then create a JAR file using the jar tool supplied by JDK. For example, you can use the following command to create the adventure-ejb.jar:

jar cvf adventure-ejb.jar *

This will create a JAR file containing all class files in the current directory, and any subdirectories below the current directory. You can automate building JAR files using several tools. Most modern IDEs support building EJB-JAR modules, and make the creation of JAR modules somewhat transparent to you. A number of specialized utilities in addition to IDEs also support the build process. Today, the most frequently used tool to assist with builds is Apache Ant (http://ant.apache.org/), although there is a strong movement toward Apache Maven (http://maven.apache.org/). Listing 2 shows a sample Ant build script that was created to automate building an EJB-JAR module. Ant build scripts are provided with our code examples and can be downloaded from Manning's (my publisher) website (www.manning.com/panda).

Listing 2 Sample script for building an EJB-JAR file

Click here for a larger image.

The EJB-JAR file must include the interfaces and bean classes. It may also include any helper classes. Optionally the helper classes may be packaged in a separate JAR file in the EAR file. You have two options:

  • The JAR containing helper classes may be packaged in the lib directory of the EAR file. Using this approach, the packaged classes will be automatically visible to all modules in the EAR module.
  • If you want to limit the visibility to only a specific EJB-JAR or WAR module, you can create an entry in the Manifest.mf file of the module that contains a Class-Path attribute to the JAR file.

Now that you know the structure of EJB-JAR and how to package it, let's look at the elements of ejb-jar.xml.

Deployment descriptors vs. annotations

An EJB deployment descriptor (ejb-jar.xml) describes the contents of an EJB module, any resources used by it, and security transaction settings. The deployment descriptor is written in XML, and because it is external to the Java byte code, it allows you to separate concerns for development and deployment.

The deployment descriptor is optional and you could use annotations instead, but we don't advise using annotations in all cases for several reasons. Annotations are great for development, but may not be well suited for deployments where settings may change frequently. During deployment it is common in large companies for different people to be involved for each environment (development, test, production, etc.). For instance, your application requires such resources as DataSource JMS objects, and the JNDI names for these resources change between these environments. It does not make sense to hard-code these names in the code using annotations. The deployment descriptor allows the deployers to understand the contents and take appropriate action. Keep in mind that even if the deployment descriptor is optional, certain settings such as default interceptors for an EJB-JAR module require a deployment descriptor. An EJB-JAR module may contain

  • A deployment descriptor (ejb-jar.xml)
  • A vendor-specific deployment descriptor, which is required to perform certain configuration settings in a particular EJB container

The good news is that you can mix and match annotations with descriptors by specifying some settings in annotations and others in the deployment descriptor. Be aware that the deployment descriptor is the final source and overrides settings provided through metadata annotations. To clarify, you could set the TransactionAttribute for an EJB method as REQUIRES_NEW using an annotation, and if you set it to REQUIRED in the deployment descriptor, the final effect will be REQUIRED.

Annotations vs. XML descriptors: the endless debate
Sugar or sugar substitute? It's a matter of choice. Zero calories versus the risk of cancer? The debate may well be endless, and the same applies to the debate between annotations and deployment descriptors. Some people find annotations elegant, while they see XML as verbose, ugly, and hard to maintain. Others find annotations unsightly, and complain that annotations complicate things by making configurations reside closer to the code. The good thing is that you have a choice, and Java EE allows you to override annotation settings in the code with deployment descriptors if you desire. We suggest you weigh the pros and cons of these options with a clear mind.

Although we won't delve deeply into deployment descriptors, let's look at some quick examples to see what deployment descriptors look like so that you can package a deployment descriptor in your EJB module if you need to. Listing 3 shows a simple example of a deployment descriptor for the BazaarAdmin EJB.

Listing 3: A simple ejb-jar.xml

Click here for a larger image.

If you are familiar with EJB 2, you may have noticed that the only notable difference between this deployment descriptor and one in EJB 2 is that the version attribute must be set to 3.0, and the home element is missing because EJB 3 does not require a home interface.

Editor's Note: The bracketed numbers in the following paragraph refer to the callouts in listing 3.

If you are using deployment descriptors for your EJBs, make sure that you set the ejb-jar version to 3.0 [1] because this will be used by the Java EE server to determine the version of the EJB being packaged in an archive. The name element [2] identifies an EJB and is the same as the name element in the @Stateless annotation. These must match if you are overriding any values specified in the annotation with a descriptor. The session-type element [3] determines the type of session bean. This value can be either stateless or stateful. You can use transaction-type [4] to specify whether the bean uses CMT (Container) or BMT (Bean). The transaction, security, and other assembly details are set using the assembly-descriptor tag of the deployment descriptor [5] and [6].

Table 3 lists commonly used annotations and their corresponding descriptor tags. Note that as we mentioned earlier there is an element for every annotation. You will need only those which make sense for your development environment. Some of the descriptor elements you'll probably need are for resource references, interceptor binding, and declarative security. We encourage you to explore these on your own.

Table 3 One-to-one mapping between annotations and XML descriptor elements

Annotation Type Annotation Element Corresponding Descriptor Element
@Stateless EJB type   <session-type>Stateless
    name ejb-name
@Stateful EJB type   <session-type>Stateful
@MessageDriven EJB type   message-driven
    name ejb-name
@Remote Interface type   remote
@Local Interface type   local
@Transaction-Management Transaction management type at bean level   transaction-type
@Transaction-Attribute Transaction settings method   container-transaction trans-attribute
@Interceptors Interceptors   interceptor-binding interceptor-class
@ExcludeClass-Interceptors Interceptors   exclude-class-interceptor
@ExcludeDefault-Interceptors Interceptors   exclude-default-interceptors
@AroundInvoke Custom interceptor   around-invoke
@PreConstruct Lifecycle method   pre-construct
@PostDestroy Lifecycle method   post-destroy
@PostActivate Lifecycle method   post-activate
@PrePassivate Lifecycle method   pre-passivate
@DeclareRoles Security setting   security-role
@RolesAllowed Security setting   method-permission
@PermitAll Security setting   unchecked
@DenyAll Security setting   exclude-list
@RunAs Security setting   security-identity run-as
@Resource Resource references
(DataSource, JMS, Environment, mail, etc.)
env- ref
  Resource injection Setter/field injection injection-target
@EJB EJB references   ejb-ref
@Persistence-Context Persistence context reference   persistence-context-ref
@PersistenceUnit Persistence unit reference   persistence-unit-ref

You can find the XML schema for the EJB 3 deployment descriptor at http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd.

Page 3 of 4

This article was originally published on April 9, 2007

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date