Packaging EJB 3 Applications
Java EE applications offer the promise of write once, run anywhere (WORA), this should clarify the portability of your application. To simplify maintenance you create a JAR to contain all your application, However, enterprise Java applications are packaged as specialized version of JAR files - EAR, WAR and EJB-JAR modules - before they can be deployed to a Java EE compliant application server.
To run your application you have to make it available to the Java EE application server, this is known as deployment. Since EJB is a core part of the Java EE specification you have to follow the Java EE standard for deployment. The deployment will contain all the components of the application - presentation, business and the persistence, you group these components into modules and each module has its own archive type.
Type |
Description |
Descriptor |
Contents |
CAR | Client application archives | application-client.xml | Thick Java client for EJBs |
EAR | Enterprise application archive | application.xml | Other Java EE modules such as EJB-JARS |
EJB-JAR | EJB Java archive | ejb-jar.xml | Session beans, message-drive beans and optionally entities. Needs a persistence.xml if entities are packaged |
RAR | Resource adaptor archives | ra.xml | Resource adapters |
WAR | Web application archives | web.xml | Web application artifacts such as servlets, JSPs, JSF, static files, etc. Entities can also be packaged in this module. Needs a persistence.xml if entities are packaged. |
I have already discussed deployment regarding the JBoss server, have a look for more details on deploying to a Java EE Server.
There is a misconception that all classes are loaded into memory when the JVM starts up, this is not true. Classes are loaded dynamically as and when they are needed at runtime, the process of locating the byte code for a given class and converting it into a Java class instance is known as class loading. However class loading is vendor specific and some vendors optimize the loading of class for example some use pooling mechanisms, also as applications grow they become more complex and library dependencies means more classes will be loaded when the JVM starts, you may see the odd ClassNotFoundException and NoClassDefFoundError.
Class loading is initially performed by the JVM when it starts up, it loads the required classes first and then the subclasses of the java.lang.ClassLoader class. These class loaders allow applications to load classes that may not be required during the compilation process. below is Sun's JVM hierarchy of three loaders
Bootstrap class loader | loads all platform classes that the Java language requires such as java.lang and java.util. You can use the optional bootclasspath command-line option to load additional classes. |
Extension class loader | this loader is the child class loader of the boot class loader, and loads class from any JAR files in the $JAVA_HOME/jre/lib/ext directory or in a separate directory specified with the -Djava.ext.dir system property. By default this loads the cryptography and security classes |
System class loader | loads the application classes as specified by an application and is also know as the application class loader. You can specify where to load the class from using the CLASSPATH environment variable, using the manifest Class-Path entry of a JAR file. |
The class loader follows a Parent First delegation model, it first see's if the class is already loaded in cache, then it checks its parent classloaders and fetches it from their cache and lastly it will read from the CLASSPATH A standard archive may load classes either packaged inside it or from any other archives it is dependent on.
Module |
Code Sources |
EAR |
|
EJB-JAR |
|
WAR |
|
I have already discussed class loading in a number of application servers
The picture below details class visibility when using multiple web modules, each child class will have access to its parent classes, so with this knowledge help classes should be packaged in the EAR lib directory.
Deployment Descriptors v Annotations
This debate will probably continue until either one dies, basically it is a matter of choice, annotations are suited to a static environment where as deployment descriptors are best in a more dynamic environment, however you can mix and match but remember that the deployment descriptor will override any annotations.
Here is a table that displays the mappings between annotations and deployment descriptor elements
Annotation |
Type |
Annotation Element |
Corresponding Descriptor Element |
@Stateless | EJB Type |
<session-type>Stateless | |
name |
ejb-name | ||
@Stateful | EJB Type |
name |
<session-type>Stateful |
ejb-name | |||
@MessageDriven | EJB Type |
message-driven | |
name |
ejb-name | ||
@Remote | Interface Type |
remote | |
@Local | Interface Type |
local | |
@TransactionManagement | Transactional management type at bean level |
transaction-type | |
@TransactionAttribute | Transaction setting method |
container-transaction trans-attribute |
|
@Interceptors | Interceptors |
interceptor-binding interceptor-class |
|
@ExcludeClassInterceptor | Interceptors |
exclude-class-interceptor | |
@ExcludeDefaultInterceptor | Interceptors |
exclude-default-interceptor | |
@AroundInvoke | Custom Interceptor |
around-invoke | |
@PostConstruct | Lifecycle Method |
post-construct | |
@PreDestroy | Lifecycle Method |
pre-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 reference (DataSource , JMS, Environment, mail, etc) |
resource-ref resource-env-ref message-destination-ref env-ref |
|
Resource injection |
Setter/field injection |
injection-target | |
@EJB | EJB references |
ejb-ref ejb-local-ref |
|
@PersistenceContext | Persistence context reference |
persistence-context-ref | |
@PresistenceUnit | Persistence unit reference |
persistence-unit-ref |
Also vendors have specific deployment descriptors for there application server
Application Server | Vendor-Specific Deployment Descriptor |
BEA Weblogic | weblogic-ejb-jar.xml |
IBM Websphere | ibm-ejb-jar.xml |
JBoss | jboss.xml |
Oracle Application Server | orion-ejb-jar.xml |
Sun GlassFish | sun-ejb-jar.xml |
The last table is detailing the persistence annotation association with deployment descriptors
Annotations Grouped by Type |
XML Element |
Object Type |
|
@Entity | entity |
@MappedSuperClass | mapped-superclass |
@Embedded | embedded |
@Embeddable | embeddable |
Table Mapping |
|
@Table | table |
@SecondaryTable | secondary-table |
Query |
|
@NamedQuery | named-query |
@NamedNativeQuery | named-native-query |
@SqlResultsetMapping | sql-result-set-mapping |
Primary Key and Column Mapping |
|
@Id | id |
@IdClass | id-class |
@EmbeddedId | embedded-id |
@TableGenerator | table-generator |
@SequenceGenerator | sequence-generator |
@Column | column |
@PrimaryKeyJoinColumn | primary-key-join-column |
@GeneratedValue | generated-value |
Relationship Mapping |
|
@ManyToMany | many-to-many |
@OneToOne | one-to-one |
@OneToMany | one-to-many |
@ManyToOne | many-to-one |
@JoinTable | join-table |
@JoinColumn | join-column |
@InverseJoinColumns | inverse-join-columns |
Listeners |
|
@ExcludeDefaultListeners | exclude-default-listeners |
@ExcludeSuperclassListeners | exclude-superclass-listeners |
@PreUpdate | pre-update |
@PostUpdate | post-update |
@PrePersist | pre-persist |
@PostPersist | post-perist |
@PreRemove | pre-remove |
@PostRemove | post-remove |
@PostLoad | post-load |