Vous êtes sur la page 1sur 35

Notes on JBoss Application Server and EJB 3.

0
Created 03/15/08
Updated 03/20/08, Updated 04/04/08, Updated 04/25/08, Updated 05/12/08, Updated 05/19/08, Updated 05/27/08
Updated 06/08/08, Updated 06/15/08, Updated 06/27/08, Updated 07/12/08, Updated 07/20/08, Updated 08/02/08
Updated 09/08/08, Updated 08/11/08, Updated 12/17/08, Updated 02/25/09, Updated 02/28/09, Updated 03/23/09
Updated 03/26/09, Updated 05/31/09, Updated 08/22/09, Updated 09/14/09

Introduction
These notes cover usage of the JBoss Application Server and the most important specification that it implements:
EJB 3.0. JBoss is a software product, and EJB3.0 is part of a larger specification called Java EE 5.0. EJB 3.0
focuses on the services that support back-end business logic and persistence, while Java EE 5.0 includes
specifications for presentation tools, security, web services, JMS, and more.
The JBoss Application Server is the latest in a series of releases of a J2EE-compliant application server. It dates
back to around 2001-2002, and has been greatly improved each year. Basically, an application server like this
provides the following:
Database connection management
Persistence management
Component development (the components are called Enterprise Java Beans)
Transaction Management
Security Management
Web Servlet Support
Clustering and Fail-Over Support
Other J2EE interfaces and standards, including JMS, JavaMail, Java Web Services, and more
JBoss is like a super-version of Tomcat, providing data management and persistence, in addition to HTTP request
processing (JBoss uses a portion of Tomcat for this purpose). JBoss includes container management of persistence,
it includes separation of web application and business logic portions; it includes the JMX infrastructure, and it
includes message-driven beans with JMS.
JBoss is such a large set of facilities that it is hard to learn which ones to use under what conditions. Hence, there
are both reference manuals, and usage-oriented tutorials.
The standard that is most specific to J2EE application servers (now called JEE application servers, with the
release of Java 5) is the Enterprise Java Bean (EJB) standard. This has been greatly revised from version 1.0 to 2.0
to 3.0. EJB 3.0 is a major step forward, and is a primary focus of this document.
While not discussed here, the major competing application server products include Suns Glassfish, and BEAs
WebLogic, IBMs WebSphere, and Oracles OC4J. In early 2008, Oracle acquired BEA.
This document begins with the release specification notes for JBoss, and then focuses on EJB 3.0 and related Java
EE 5.0 services for the main text. Then it concludes with a number of JBoss-based examples, derived from the
Workbook part of the Burke and Monson-Haefel book. This document also contains a number of places where
Seam is discussed, particularly how Seam extends the session bean management facilities to provide stateful
components.

JBoss Current Version and Downloads


The current stable version of JBoss is 5.1.0.GA, released May 23, 2009. The 5.x.x series is important because it is
the first version implementing all of Java EE 1.5. However, many development efforts are still on the 4.2.x series,
and this document was initially written for the 4.2.x series. So we will ignore the 5.0.x/5.1.x series for now.

Page 1 of 35

The current 4.2.x version as of this writing is 4.2.3.GA released July 18, 2008. The 4.2.x versions are important
because they are the first versions to deploy EJB3 natively. The 4.2.3 version includes a number of fixes and
number of updated dependent libraries such as JSF, JAX-WS, JBoss Cache, and Javassist. Specific patches in 4.2.3
include:

Upgrade jboss transactions to 4.2.3.SP7 (from 4.2.3.SP6)


Upgrade JSF to 1.2_08
Upgrade jboss cache to 1.4.1.SP7 (from 1.4.1.SP5)
Upgrade to jbossxb 1.0.0.SP3 (from 1.0.0.SP1)
All the known bind address properties should be set to the default bind address
Upgrade jboss remoting to v2.2.2.SP5 (from v2.2.2.SP1)
Transaction variable is not reset in ejb2 inflow interceptor
Upgrade jbossws to 2.0.4.GA (from 2.0.1.SP2)
Add a transaction status interface for the connection manager and implement it in TxConnectionManager
Add the transaction active check to the jdbc resource adapter
Add the transaction active check to the jms resource adapter
Upgrade javassist to 3.8.0.GA
Upgrade jboss remoting to v2.2.2.SP8 (from v2.2.2.SP5)
Upgrade to the latest JSF implementation 1.2_09 (from 1.2_08)
Upgrade JBoss Cache to 1.4.1.SP9

The 4.2.x releases are considered transitional between 4.x and 5.x, because they implement EJB 3.0, but are still
considered a Java EE 1.4 product rather than Java EE 5. With mostly new support for JEE tools and technologies
that are key to Java EE 5. The major new improvements in 4.2.x include:

Full support of JAX-WS, by including version 2.0.x of JAX-WS as the web services implementation
Full support of Java 1.6
Tomcat 6.0, which adds support for JSP 2.1 and Servlet 2.5
JavaServer Faces 1.2 integration (this is based on Suns implementation)
JBoss Transactions (Arjuna) JTA 4.2.3 as the default transaction monitor
Integration of Hibernate 3.2.3.GA
Integration of Hibernate Annotations 3.3.0.GA

There were a number of 4.0.x versions, which implement a Java EE 1.4 application server, with embedded Apache
Tomcat 5.5. They included JavaServer Faces 1.1 (using Apache MyFaces). Any Java Virtual Machine
implementation between versions 1.4 and 1.5 is supported. The 4.0.x versions of JBoss were released in late 2005
through 2007.

Resources
JBoss in Action: Configuring the JBoss Application Server by Javid Jamae and Peter Johnson. Manning Press,
January 2009, 496 pages. List price $49.99, Amazon price $31.49, used from $23.77. Rated 5 stars on Amazon.com
(from 3 reviews). This is the first book to focus on teaching readers in detail how to use the JBoss application
server. Unlike other titles about JBoss, the authors of JBoss in Action go deeper into the advanced features and
configuration of the server. In particular, it focuses on enterprise-class topics, such as high availability, security, and
performance. This book walks readers through the JBoss 5 Application Server from installation to configuration to
production development. It is not as much of a developers guide as it is an administrators guide and an architects
guide to some of the advanced features, which include JBoss Seam and JBoss Portal.
Enterprise Java Beans 3.0 (Fifth Edition) by Bill Burke and Richard Monson-Haefel. OReilly Press, May 2006,
760 pages. List price $49.99, Amazon price $34.66, used from $20.12. Rated 4.5 stars on Amazon. This fifth
edition, written by Bill Burke and Richard Monson-Haefel, has been updated to capture the very latest need-to-know
Java technologies in the same award-winning fashion that drove the success of the previous four strong-selling

Page 2 of 35

editions. Bill Burke, Chief Architect at JBoss, Inc., represents the company on the EJB 3.0 and Java EE 5
specification committees. Richard Monson-Haefel is one of the world's leading experts on Enterprise Java. The
book is organized into two parts: the technical manuscript followed by the JBoss workbook. The technical
manuscript explains what EJB is, how it works, and when to use it. The JBoss workbook provides step-by-step
instructions for installing, configuring, and running the examples from the manuscript on the JBoss 4.0.x
Application Server. Buy this book.
EJB 3 in Action by Panda, Rahman, and Lane. Manning Press, April 2007, 712 pages. List price $49.99, Amazon
price $39.40, used from $34.50. Rated 4 stars on Amazon.com. Considered to be a very nice and broad developers
guide coverage of EJB 3 with a very simple and excellently crafted case study. The book starts very lightly on this
complex subject and slowly dives into the details of advanced concepts like JPA, interceptors, transactions, security,
and performance issues. If develops each facility within the case study. We liked the idea of case study starting
simple and developing it based on complexity. Some reviews stated that it was a very good book with a very
smooth read, while other reviews stated that it was poorly worded, however. The book also has comparisons of EJB
3 with Spring. This book is available as an e-book in the IEEE Computer Society Safari bookshelf.
Beginning EJB 3 Application Development: From Novice to Professional by Kodali, Weatherby, and Zedroni.
APress, September 2006, 512 pages. List price $44.95, Amazon price $35.66, used from $17.88. Rated 4 stars on
Amazon. Opinions varied greatly, from 1 star to 5 stars. Similar in content to the above books.
JBoss at Work by Tom Marrs and Scott Davis. OReilly Press, 306 pages, October 2005. List price $34.95,
Amazon price $23.07, used from $18.66. Rated 4.5 stars on Amazon.com. Described as a great overview of a broad
spectrum of product technologies. It spends enough time on each to get them working and to provide a feel for their
value, customizability, and flexibility. Examples are well-presented and contain discussion about how they work
and are configured for multiple popular application environments, where appropriate. It has excellent background
and history for each technology, popular alternatives, and a discussion about why the author preferred this particular
technology. In other words, the authors provide more than just the bare mention included in many "survey" books.
There is enough to get all of them working, and working together as a cohesive set. It does not, however, provide a
lot of detail on each one. Unfortunately the book represents a transition between the EJB 2.0 world and the EJB 3.0
world, and hence many examples are described in terms of EJB 2.0. It uses JBoss 4.0.x rather than 4.2.x.
Mastering Enterprise JavaBeans 3.0 by Sriganesh, Brose, and Silverman, Wiley, July 2006, 685 pages. List price
$44.99, Amazon price $29.19, Used from $19.55. Rated 4 stars on Amazon.com. Opinions varied greatly, some
comments indicating that it was a great reference, others thinking that it was little more than the online tutorial. We
have a copy from the Palo Alto library. The most useful chapter is a comparison of EJB 2.0 and 3.0.
JBoss: A Developers Notebook by Norman Richard. O'Reilly Media, Inc., June 2005, 172 pages. Rated 4 stars
on Amazon. List price $29.99, Amazon price $19.33, used from $7.90. This is perhaps the oldest book that is still
relevant, though it still predates EJB 3.0. However, it provides a very friendly and try things out style of writing,
which we have found useful when learning something new and complex for the first time.

JBoss-Provided Documentation
There is basically no documentation in the download itself. There are four examples, but these are not particularly
relevant to our projects and usage of JBoss or EJB 3.0.
Instead you should read the JBoss Getting Started online book at
http://docs.jboss.org/jbossas/getting_started/v4/html/
These are focused on a tutorial called the Dukes Bank application, which has account and transaction records. This
is quite useful, as it builds out entity beans, session beans, and more.

Page 3 of 35

Architectural Overview of EJB 3.0


EJB 3.0 defines a container, which supports component-based development and deployment of applications. The
components are called Entity Beans, Session Beans and Message-driven Beans (each to be defined below). The
container also supplies a variety of services for which the most important one is a persistence service, called JPA.
The relationship is as shown below:

Examples of the other services include state management, transactions, clustering, messaging, timers, etc. Java EE 5
and EJB 3.0 can be thought of as a virtual machine like the JVM itself, but with support for enterprise
applications. This way of thinking about Java EE 5 appeared in the Panda, Rahman, and Lane book and seems quite
on target.
EJB 3.0 is an outgrowth of the earlier EJB 2.x specification, which included most of the above, including all of the
persistence facilities, however, EJB 3.0 is far easier to use, as it is built around POJOs plus Java Annotations.
The EJB 3.0 specification was generated from about 2003 to 2005, and has led to a major resurgence of JEE servers
and tools.
The biggest changes in the EJB 3.0 specification are the removal of deployment descriptors and the new
specification for persistence, called the Java Persistence API. This new API is very heavily based on facilities
within Hibernate, and while an App Server may use Hibernate underneath (JBoss does), the API has definitions
within packages such as javax.persistence that provide a wrapper over Hibernate and hence you dont see it directly.

The Entity Bean


Entity beans in the EJB 3.0 model are defined by starting with a POJO, and then mapping it to the tables of the
relational database via annotations. A POJO becomes an entity bean simply by having the @Entity annotation.
Other annotations include the table name, and the getters contain information about the column names.
Unlike EJB 2.1, in which entity beans were abstract, Java Persistence entity beans are real objects. They dont
implement any particular EJB interface.
Entities are persisted and fetched through the EntityManager which is part of the persistence service, which is
similar to the Hibernate Session object. It provides operations such as persist(), and createQuery().

The Session Bean


A Session Bean represents a distributable object that carries out a function or service, and comes in two forms:
session beans and message-driven beans. Session beans tend to manage particular kinds of activities, such as the act
of making a reservation with a travel agent. A TravelAgent session bean, example, must use a Cruise, a Cabin, and a
Customerall entity beansto make a reservation.
The relevant distinction within the scope of EJB and Java Persistence is that an entity bean has persistent state, while
session and message-driven beans model interactions but do not have a persistent state.

Page 4 of 35

An example would be the TravelAgent and ReservationProcessor session beans, which are responsible for making a
reservation, can even access the database directly, and perform reads, writes, and updates to the data. But theres no
Travel Agent or ReservationProcessor record in the database.
A session bean has a remote interface and a local interface. The former is an interface annotation with @Remote,
and the latter is annotated @Local. These indicate the importance given to Java Annotations within EJB 3.0, while
it is still possible to use XML deployment descriptors to define the same thing.
A typical example would be:
@Remote
public interface CalcuatorRemote {
public int add(int x, int y);
public int subtract(int x, int y);
}

Within the implementation being (@Stateless defines a stateless session bean)


@Stateless
public class CalculatorBean implements CalculatorRemote {
public int add(int x, int y) { return x+y; }
public int substract(int x, int y) { return x-y; }
}

The local interface would be defined in a similar way.


The EJB container is responsible for the invocation and security, and other issues of the environment, so that
developers deal only with the beans and the business-level code. We will see that a variety of additional annotations
control these features of the container.

The Message-Driven Bean


Just as session beans process direct business requests from the client, MDBs process indirect messages. In
enterprise systems, messaging has numerous uses, including system integration, asynchronous processing, and
distributed system communication. If you've been working on enterprise development for some time, you're
probably familiar with at least the idea of messaging. In the most basic terms, messaging involves communicating
between two separate processes, usually across different machines. Java EE messaging follows this same ideajust
on steroids. Most significantly, Java EE makes messaging robust by adding a reliable middleman between the
message sender and receiver.

Services
In this section, we briefly introduce some of the services that an EJB container offers. Obviously, we can't explain
the implementation details of each service in this section. Neither is it necessary to cover every service EJB offers
right now. The table below from the Panda, Rahman, and Lane book briefly lists the major EJB 3 services and
explains what they mean to you from a practical perspective.
Service

Applies To

What It Means for You

Integration

Session
beans and
MDBs

Helps glue together components, ideally through simple configuration instead


of code. In EJB 3, this is done through dependency injection (DI) as well as
lookup.

Pooling

Stateless
session
beans,
MDBs

For each EJB component, the EJB platform creates a pool of component
instances that are shared by clients. At any point in time, each pooled instance
is only allowed to be used by a single client. As soon as an instance is finished
servicing a client, it is returned to the pool for reuse instead of being frivolously
discarded for the garbage collector to reclaim.

Page 5 of 35

Service

Applies To

What It Means for You

Thread-safety

Session
beans and
MDBs

EJB makes all components thread-safe and highly performant in ways that are
completely invisible. This means that you can write your server components as
if you were developing a single-threaded desktop application. It doesn't matter
how complex the component itself is; EJB will make sure it is thread-safe.

State management

Stateful
session
beans

The EJB container manages state transparently for stateful components instead
of having you write verbose and error-prone code for state management. This
means that you can maintain state in instance variables as if you were
developing a desktop application. EJB takes care of all the details of session
maintenance behind the scenes.

Messaging

MDBs

EJB 3 allows you to write messaging-aware components without having to deal


with a lot of the mechanical details of the Java Messaging Service (JMS) API.

Transactions

Session
beans and
MDB

EJB supports declarative transaction management that helps you add


transactional behavior to components using simple configuration instead of
code. In effect, you can designate any component method to be transactional. If
the method completes normally, EJB commits the transaction and makes the
data changes made by the method permanent. Otherwise the transaction is
rolled back.

Security

Session
beans

EJB supports integration with the Java Authentication and Authorization


Service (JAAS) API, so it is very easy to completely externalize security and
secure an application using simple configuration instead of cluttering up your
application with security code.

Interceptors

Session
beans and
MDBs

EJB 3 introduces AOP in a very lightweight, accessible manner using


interceptors. This allows you to easily separate out crosscutting concerns such
as logging, auditing, and so on in a configurable way.

Remote access (also Session


called Distributed in beans
the Burke book)

In EJB 3, you can make components remotely accessible without writing any
code. In addition, EJB 3 enables client code to access remote components as if
they were local components using DI.

Web services

Stateless
session
beans

EJB 3 can transparently turn business components into robust web services
with minimal code change.

Persistence

Entities

Providing standards-based, 100 percent configurable automated persistence as


an alternative to verbose and error-prone JDBC/SQL code is a principal goal of
the EJB 3 platform.

Caching and
performance

Entities

In addition to automating persistence, JPA transparently provides a number of


services geared toward data caching, performance optimization, and application
tuning. These services are invaluable in supporting medium to large-scale
systems.

Deployment
An application consists of class file and their other resources zipped up into EAR file, which is a special kind of
JAR file. Upon opening the JAR file, the EJB container scans all classes for annotations such as @Stateless to find
these special classes there is no directory or manifest maintenance that is needed.

Naming in the Container


Naming is all based on JNDI, however, in EJB3, this naming operation is carried out by annotations, rather than
writing a JNDI mapping file.

Page 6 of 35

There are number of important naming conventions that are often used, such as having all beans have names that
end in impl, or bean. While this was more important in EJB 2, it is less critical in EJB 3, because there are
fewer classes to define.

Entity Beans Introduction


Use a POJO and add the @Entity annotation.
Then create getters and setters.
There are really no other requirements for a simple entity bean. However, as we will see in the section below, there
many additional annotations that can be used to specify persistence mapping, such as table names, columns names,
id management, and relationships.

Session Beans
This is most critical area of understand the EJB 3.0 model, since we are already familiar with concepts of persistence
from our experience with Hibernate.

Stateless Session Beans


A stateless session bean has one or more business interfaces, typically grouped into related sets on each session
bean. It will typically interact with the persistence facilities, but no content can be preserved from one call to
another. This means that all information must be provided in the arguments to each method. An example would be
a payment bean that uses a payment table.
The arguments can be entities themselves, as long as all content is serializable. This an improvement over EJB 2.1
where one had to write parallel value object classes if one wanted to pass around the state of an entity instead of
access it through the old remote interface model.
A session bean can have remote and local interfaces. It can also throw exceptions.
You can place the @Remote and @Local annotations on the interface specification or on the bean itself. When used
on bean class, the annotations take an array of interface classes. It is not recommended that you use this approach
unless you have to, as having business interfaces available to programmers means that they enforce the contract
between the bean class and the calling code.
A session bean can access the SessionContext, which allows you to get the current user accessing the EJB, because it
extends EJB context, and that contains the method getCallerPrincipal() and isCallerInRole(String roleName).
The lifecycle of a session bean is very simple, as it has only two states: Does Not Exist and Method-Ready Pool.
The former is a default state when no such instance exists. The latter is when the instance has been constructed (i.e.,
after class.newInstance(), injection processing, and running the @PostConstruct method if present).
It is rare for a stateless session bean to change from Method-Ready to not existing, but it can if the server decides to
reduce memory. In this case, the @PreDestroy method will be called first.

Stateful Session Beans


Each stateful session bean is dedicated to one client for the life of the bean instance. A stateful session bean has
conversational content. It doesnt have persistent content, however, meaning that nothing reaches the database by
itself.
Stateful session beans are often considered extensions of the client. It allows you to move business logic to the
server and therefore thin the client.

Page 7 of 35

A new instance of a stateful session bean is made each time that it is looked up. The instance is released after some
configurable timeout period.
The lifecycle of a stateful session bean is more complex, as it can be passivated by the server to save resources.
This means that it will be serialized, and stored somewhere. It can be reactivated if there is new traffic (requests)
from the original client. The stateful session bean goes through all of the same container-based method processing
(such as @PostConstruct) that applies to stateless session beans.
Multiple methods can be decorated with the @Remove method. This means that the session bean state can be
removed after that method completes.
Extended persistence contexts are an advanced concept that we dont use as yet. They have the benefit of leaving all
of the objects that are being used remaining the active or managed state.
With Seam, we dont deal with Stateful vs. Stateless session beans, because all session-objects are stateful
components, and you just select their lifetime. For instance the lifetimes can be anything from event (basically no
long-term state, hence stateless) to conversation or session (different variations on stateful session beans).

Example
Here is an example of a session bean from the EJB3 book:
@Stateful
public class TravelAgentImpl implements TravelAgent {
@PersistenceContext
private EntityManager entityManager;
@EJB
private ProcessPaymentLocal process;
private Customer customer;
private Cruise
cruise;
private Cabin
cabin;
public void setCustomer(Customer cust) {
entityManager.create(cust);
this.customer = cust;
}
public void setCabinId(int id) {
this.cabin = entityManager.find(Cabin.class, id);
}
public void setCruiseId(int id) {
this.cruise = entityManager.find(Cruise.class, id);
}
public Reservation bookPassage(String card, double price)
throws IncompleteConversationalState {
if (customer == null || cruise == null || cabin ==null) {
throw new IncompleteConversationalState();
}
try {
Reservation reservation =
new Reservation(customer, cruise, cabin, price, new Date());
entityManager.persist(reservation);
process.byCredit(customer, card, price);
return reservation;
}

Page 8 of 35

catch (Exception ex) {


throw new EJBException (e);
}
}
}

Some of the important aspects of this example are the injection of the persistenceContext, and the reference to the
other EJB session bean. Also note how there is state in the session bean, such as the this.customer variable. For
this reason, the Session bean must be declared @Stateful. A stateless session bean has methods for which all input
is located in the parameters.
The lifecycle of stateful session is only as long as the conversation. A conversation is started when the stateful
session bean is looked up, and completed when the conversation times out.

Coding Session Beans


Like all EJB 3 beans, session beans are POJOs that follow a small set of rules. The following summarizes the rules
that apply to all types of session beans:
A session bean must have at least one business interface.
The session bean class must be concrete. You cannot define a session bean class as either final or abstract
since the container needs to manipulate it.
You must have a no-argument constructor in the bean class. As we saw, this is because the container
invokes this constructor to create a bean instance when a client invokes an EJB. Note that the compiler
inserts a default no-argument constructor if there is no constructor in a Java class.
A session bean class can subclass another session bean or any other POJO. For example, a stateless session
bean named BidManager can extend another session bean PlaceBidBean in the following way:
@Stateless
public BidManagerBean extends PlaceBidBean implements BidManager {
...
}

The business methods and lifecycle callback methods may be defined either in the bean class or in a
superclass. It's worth mentioning here that annotation inheritance is supported with several limitations with
EJB 3 session beans. For example, the bean type annotation @Stateless or @Stateful specified in
the PlaceBidBean superclass will be ignored when you deploy the BidManagerBean. However, any
annotations in the superclasses used to define lifecycle callback methods (more about that later in this
section) and resource injections will be inherited by the bean class.
Business method names must not start with "ejb." For example, avoid a method name like ejbCreate or
ejbAddBid because it may interfere with EJB infrastructure processing. You must define all business
methods as public, but not final or static. If you are exposing a method in a remote business interface of the
EJB, then make sure that the arguments and the return type of the method implement the
java.io.Serializable interface.

Here is a summary of the callback methods


Callback Annotation

Type of EJB Typically Used For...

javax.annotation.
PostConstruct

Stateless,
stateful,
MDB

This annotated method is invoked after a bean instance is


created and dependency injection is complete. Generally this
callback is used to initialize resources (for example, opening
database connections).

javax.annotation.
PreDestroy

Stateless,
stateful,
MDB

This annotated method is invoked prior to a bean instance being


destroyed. Generally this callback is used to clean up resources
(for example, closing database connections).

Page 9 of 35

Callback Annotation

Type of EJB Typically Used For...

javax.ejb.PrePassivate

Stateful

This annotated method is invoked prior to a bean instance being


passivated. Generally this callback is used to clean up
resources, such as database connections, TCP/IP sockets, or any
resources that cannot be serialized during passivation.

javax.ejb.PostActivate

Stateful

This annotated method is invoked after a bean instance is


activated. Generally this callback is used to restore resources,
such as database connections that you cleaned up in the PrePassivate method.

These are the only few stateful beanspecific features that we needed to talk about! Before concluding this section
on stateful beans, we'll briefly summarize the differences between stateful and stateless session beans as a handy
reference:
Features

Stateless

Stateful

Conversational state

No

Yes

Pooling

Yes

No

Performance problems

Unlikely

Possible

Lifecycle events

PostConstruct,
PreDestroy

PostConstruct, PreDestroy,
PrePassivate, PostActivate

Timer

Yes

No

SessionSynchronization for
transactions

No

Yes

Web services

Yes

No

Extended PersistenceContext

No

Yes

Persistence using the Entity Manager


Introduction
This is largely new material in 3.0, and begins with the idea that entities are POJO, and the entity manager is a
Hibernate-like Session, called the PersistenceContext. In fact, as mentioned above, JBoss EJB 3.0 is built on top of
Hibernate 3.0 ORM solution.
For developers with experience in Hibernate, this is very similar and familiar. In general, all of the Hibernate names
and conventions have been changed to wrapper names and functions. For instance, most of the file called
persistence.xml is equivalent to the hibernate.cfg.xml file. However, there are different facilities for specifying
the class files to review for mapping information.
The interface to the EntityManager is:
package javax.persistence;
public interface EntityManager {
public void persist(Object entity);
public <T> T find(Class <T> entityClass, Object primaryKey);
public <T> T getReference(Class <T> entityClass, Object primaryKey);
public <T> T merge(T entity);

Page 10 of 35

public void remove(Object entity);


public void lock(Object entity, LockModeType lockMode);
public void refresh(Object entity);
public boolean contains(Object entity);
public void clear( );
public
public
public
public

void joinTransaction( );
void flush( );
FlushModeType getFlushMode( );
void setFlushMode(FlushModeType type);

public
public
public
public
public

Query
Query
Query
Query
Query

createQuery(String queryString);
createNamedQuery(String name);
createNativeQuery(String sqlString);
createNativeQuery(String sqlString, String resultSetMapping);
createNativeQuery(String sqlString, Class resultClass);

public Object getDelegate( );


public void close( );
public boolean isOpen( );
}

The most commonly used methods are persist(), find(), merge(), remove(), lock(), and createQuery();
You obtain an entity manager by using the @PersistenceContext annotation, such as
@PersistenceContext
private EntityManager entityManager;
This will get the default EntityManager, whose definition is created through the persistence.xml file and its related
data source definition files.
There are other ways of getting an entityManager, which allow for special attributes to be defined, or to have
multiple entityManagers each for a different data source.

Defining Persistence Units


A persistence unit is a fixed set of classes, and an entity manager maps these classes to a particular database. You
can have several persistence units defined in your deployment. Here's an example of a persistence.xml file.
<persistence>
<persistence-unit name="manager1">
<jta-data-source>java:/DefaultDS</jta-data-source>
<jar-file>../MyApp.jar</jar-file>
<class>org.acme.Employee</class>
<class>org.acme.Person</class>
<class>org.acme.Address</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
</properties>
</persistence-unit>
</persistence>

name
You are required to name your persistence unit. If your persistence classes are within a EJB JAR archive,
and it is the only persistence unit defined, then you do not have to reference this name explicitly in your
@PersistenceContext and @PersistenceUnit annotations.
jta-data-source, non-jta-data-source

Page 11 of 35

This is the JNDI name of where the javax.sql.DataSource is located. This is ignored when *not* used
within an application server. When running outside of an application server, you must specify JDBC
connections with Hibernate specific properties (see below). If you're running inside JBoss, put the jndi
name of the datasource you defined in the earlier section. Remember to put the "java:/" in front of the jndi
name you selected for your datasource.
jar-file and class
The class element specifies a fully qualified classname that you will belong to the persistence unit. The jarfile element specifies another jar you want automatically scanned for @Entity classes. When using jar-file,
you must specify a path relative to the jar file the persistence.xml file is in. By default also, the jar the
persistence.xml file is placed in is scanned for @Entity classes as well. Hence you dontoften have to
specify the <jar-file> or <class> elements.
properties
The properties element is used to specify vendor specific properties. This is where you will define your
JBoss and Hibernate specific configurations. You may need to provide information to Hibernate so that it
knows the database vendor dialect (MySQL, Oracle, etc...), caching, as well as other settings.

Simple Operations Supported by the Entity Manager


The entityManager can perform a query for one or more objects. An example of the simplest query is:
SalesOrder so = entityManager.find(SalesOrder.class, 1);

which would find a SalesOrder with primary key 1 (the assumption here is that the class has a single-part primary
key). The entityManager maps database tables to objects. If there is no object, then the find() method return null.
There is a similar method, called getReference(), which will return an exception of the record is not found.
In EJB 3, there is also a query language, which is based on Hibernates HQL. This is covered in more detail below.
The query language saves you from having to write finder methods for each of the different types of queries, as done
in EJB 3.
To write out a changed object, use the persist(Object object) method.
While most of our applications use persistence session that are maintained as long as we need them (because they
are part of Seam conversations), the EJB literature goes through a bit of detail to discuss the idea of objects that are
part of persistence sessions (in which changes to them are not actually written out until the end of the session), or the
idea of detached objects. The latter are ones that were found as part of a persistence session, but are still used after
the session is closed. Such objects can be serialized out to client, then brought back and merged in. The CAE
Online application worked this way.
Another important note is that one can force changes to be synchronized with the database by calling flush(). By
default flushing automatically happens before a correlated query is executed (inefficient implementations may flush
before any query is executed) and at transaction commit time. You can control this flush behavior with the
FlushModeType value, which is set on the entityManager. See Monson-Haefel pages 81-82.
Finally, it is possible to get a reference to the underlying persistence provider by calling
entityManager.getDelegate(). In JBoss, this will be Hiberate.
Below, we will discuss more advanced aspects of entities, and use of transactions.

Mapping Persistent Objects


Mapping in this case refers to defining the mapping between the objects and the database. This uses the EJB 3.0
version of the Hibernate mapping facilities, called Java Persistence. It is heavily based on Java Annotations.

Page 12 of 35

The most important annotations are @Table, @Column, @ManyToOne, @JoinColumn, etc.
Since the Java Persistence using Hibernate book (from Manning) covers the same concepts in a little more detail,
see our document Notes on Hibernate for more information. The Burke and Monson-Haefel EJB 3.0 book takes
almost 3 chapters to cover this material.

Basic Annotations
The annotations covered are @Entity, @Table, @Column, @Id, and more.
This chapter in the Burke and Monson-Haefel book also covers the @TableGenerator annotation and the
@SequenceGenerator.
Property mappings include @Transient, @Basic, and @FetchType. There are also @Embedded objects, and
@Temporal. The latter is important to indicate that the mapping of a property whose type is java.util.Date or
java.util.Calendar is to be a Date, a Time, or a Timestamp. By default, timestamp is assumed.

Entity Relationships
Within Java Persistence, you define relationships between objects using the @ManyToOne annotation, and other
annotations. Most of the EJB literate goes through this in great detail, because the community of EJB 2.0
developers has not seen Hibernate before.
Hence, the material is very similar to the chapter in the Hibernate book on advanced mappings and relationships.
It also defines behavior such as Cascade, Persist, and Merge. Again, these parallel the Hibernate material.

Entity Inheritance
This material is also parallel to the Hibernate book, covering approaches to defining inheritance relationships in the
O-R mapping. Since the Hibernate book covers it just as well, we have not paid a great deal of attention to this
chapter itself.

Queries and EJB QL


Querying is a fundamental feature of a relational database. A query allows you to fetch from persistence storage.
The basic query facility is the Structured Query Language (SQL), however, tools like Hibernate and Java Persistence
provide a higher level facility as well.
The high level facility is called EJB QL and is a declarative query language tailored to work with Java objects
rather than a relational schema. To execute queries, you reference the properties and relationships of your entity
beans rather than the underlying tables and columns these objects are mapped to. When the query is executed, the
entity manager uses the information you provided through the mapping metadata, and automatically translates it to
one (or several) native SQL query. The results are then converted back into objects.
Since EJB QL is a query language that represents Java objects, it is portable across different database
implementations because the entity manager handles the conversion to raw SQL for you. This appears to include
standardizing a number of dialect-specific database functions and query syntax rules.
The query facilities include an API for building conditions, support for paging, and support for ordering, etc.
See the discussion in Chapter 9 of the Burke and Monson-Haefel EJB 3.0 book.

Query Syntax
The basic syntax is select <identifier> from <tableName> <identifier>.
You can also have select <identifier> from <tableName> <identifier> where <condition>

Page 13 of 35

The condition can have parameters such as select c from Customer c where c.firstName=:first and
c.lastName=:last. In this case you would specify the parameters values on the query object.
Two syntaxes are provided: named parameters and positional parameters. Named parameters are recommended.
Typically, we are fetching a set of objects, such as Customer in the above object. In this case the result will be a
List<Customer> object. The Java class for Customer is found by searching from the package containing the query
call, then searching upwards. Typically, the class names are either the name of the class that defines the entity or are
package-absolute.
These examples return objects. However, we can return information which is more basic, as in the example:
select c.firstName, c.lastName from Customer as c

In this case, the result will be a list of the Object arrays, and the values will be stored into each Object array
positionally (i.e., firstName is at [0], and lastName is at [1]). This also avoids the column numbers in JDBC being
numbered from 1 issue.
The constructor to be used for the object can be specified. Lets say that we want to return a firstName/lastName
pair as an instance of the Name class, which has fields called first and last, and an appropriate constructor. You
could then write:
select new com.incra.Name(c.firstName, c.lastName) from Customer c

You can also query for specific fields on the record, and for related records. For example:
select so.creditCard.creditCardCompany.address.state from SalesOrder so.

Joins and other Query Facilities


Many relationships between entity beans are collection-based, and being able to access and select bens from these
releaitonsips is important.
The following query uses the IN operator to select elements from a collection. It returns the reservations of all the
customers:
select r from Customer c, in( c.reservations ) r

This query can also be expressed as an inner join (which is more familiar to SQL programmers):
select r from Customer c inner join c.reservations r

The left join syntax enables retrieval of a set of entities where matching values in the join statement may not exist.
For such values, a null value is placed in the result. Here is an example:
select c.firstName, c.lastName, p.number from Customer c left c.phonenumbers p

This can also be expressed as left outer join (syntactic sugar to parallel SQL 92).
The important point here is that the joins are expressed in terms of the fields in the object (such as c.phonenumbers)
rather than writing out the id matches that are typical of joins. Further, the metadata in the class object indicates
what class the joined tables are to be found through (notice that the class of p is never specified here only the
origin class of Customer must be specified).
The fetch join syntax allows you to preload a returned entitys relationships even if the relationship property has a
FetchType of Lazy. For example, lets say we have a defined our customers one-to-many relationship to Phone as
follows:

Page 14 of 35

@OneToMany(fetch=FetchType.LAZY)
public Collection<Phone> getPhones() { return phones; }

The default for fetchType is EAGER, except for a ManyToMany and a OneToMany relationship, for which the
default is LAZY. A fetchType of EAGER means that a persistence provider will load the attribute of an entity
along with the entity, whereas a fetchType of LAZY is a hint to the provider that the attribute need not be fetched
along with the entity.
If we were to loop over a list of customers, and call getPhones() on each one, there would be an additional query
created for each one. This is called an N+1 queries problem. Instead, use
select c from Customer c LEFT JOIN FETCH c.phones

The key in this example is the word JOIN, which causes a join to be made in the resulting query. Now the phones
will be loaded in join when the customers are loaded.
Note that in Hibernate, you can specify a runtime how the fetches are to be carried out by calling
setFetchMode(attributeName, fetchMode). However, there is no similar function in the regular EJB3 persistence
manager, so you must deal with this in the structure of the query strings.
A query can have a where clause which is basically the same as in regular SQL (we are skipping over the
discussion about arithmetic operations in where clauses that appears on pages 185 to 187 of the Burke and MonsonHaefel book).
There are also facilities for comparing with NULL and NOT NULL.
The discussion regarding order by and group by is basically the same as in SQL and Hibernate. You must be
careful which basic fields you use in the ORDER BY clause. If the query selects a collection of entities, then the
ORDER BY clause can be used with only basic fields of the entity type that is selected.
Finally, the EJB 3 query language supports the operators such as max/min/sum/avg on the specific fetched basic
fields of the entities.
Also finally, the EJB query language supports subqueries (or subselects). I dont know what happens if the
underlying database doesnt support such, perhaps it breaks the queries up into distinct ones.

Query API
package javax.persistence;
public interface Query {
public List getResultList( );
public Object getSingleResult( );
public int executeUpdate( );
public Query setMaxResults(int maxResult);
public Query setFirstResult(int startPosition);
public Query setHint(String hintName, Object value);
public Query setParameter(String name, Object value);
public Query setParameter(String name, Date value, TemporalType temporalType);
public Query setParameter(String name, Calendar value, TemporalType temporalType);
public Query setParameter(int position, Object value);
public Query setParameter(int position, Date value, TemporalType temporalType);
public Query setParameter(int position, Calendar value, TemporalType temporalType);
public Query setFlushMode(FlushModeType flushMode);
}

Page 15 of 35

The three most common calls are: getResultList(), getSingleResult(), and executeUpdate(). The getSingleResult()
will throw a NonUniqueResultException if more than one record meets the query condition.
Queries are made using the following API on the EntityManager:
package javax.persistence;
public interface
public Query
public Query
public Query
public Query
public Query
}

EntityManager {
createQuery(String ejbqlString);
createNamedQuery(String name);
createNativeQuery(String sqlString);
createNativeQuery(String sqlString, Class resultClass);
createNativeQuery(String sqlString, String resultSetMapping);

Query Examples
public List findByName(String first, String last) {
Query query = entityManager.createQuery(
"from Customer c where c.firstName=:first and
c.lastName=:last");
query.setParameter("first", first);
query.setParameter("last", last);
return query.getResultList( );
}

Paging Results
Sometimes an executed query returns too many results. For instance, maybe we're displaying a list of customers on
a web page. The web page can display only so many customers, and maybe there are thousands or even millions of
customers in the database. The Query API has two built-in functions to solve this type of scenario:
setMaxResults( ) and setFirstResult( ):
public List getCustomers(int max, int index) {
Query query = entityManager.createQuery("from Customer c");
return query.setMaxResults(max).
setFirstResult(index).
getResultList( );
}

The getCustomers( ) method executes a query that obtains all customers from the database. We limit the
number of customers it returns by using the setMaxResults( ) method, passing in the max method parameter.
The method is also designed so that you can define an arbitrary set of results that you want returned by the execution
of the query. The setFirstResult( ) method tells the query what position in the executed query's result set
you want returned. So, if you had a max result of 3 and a first result of 5, customers 5, 6, and 7 would be returned.
We set this value in the getCustomers( ) method with the index parameter. Let's take this method and write
a code fragment that lists all customers in the database:
List results;
int first = 0;
int max = 10;
do {
results = getCustomers(max, first);
Iterator it = results.iterator( );
while (it.hasNext( )) {
Customer c = (Customer)it.next( );
System.out.println(c.getFirstName() + " " + c.getLastName( ));
}
entityManager.clear( );

Page 16 of 35

first = first + results.getSize( );


} while (results.size( ) > 0);

In this example, we loop through all customers in the database and output their first and last names to the system
output stream. If we had thousands or even millions of customers in the database, we could quickly run out of
memory, as each execution of the getCustomers( ) method would return customers that were still managed by
the entity manager. So, after we are finished outputting a block of customers, we call
EntityManager.clear() to detach these customers and let them be garbage-collected by the Java VM. Use
this pattern when you need to deal with a lot of entity objects within the same transaction.

Using Native Queries


If your query does not match the standard pattern of return an object or a list of objects (this is quite common for
queries including GROUP BY clauses or complex joins), you can use the createNativeQuerymethod of the
EntityManagerinterface to create a dynamic query using SQL as follows:
Queryq=em.createNativeQuery("SELECTuser_id,first_name,last_name"+
"FROMusersWHEREuser_idIN(SELECTseller_idFROM"+
"itemsGROUPBYseller_idHAVINGCOUNT(*)>)",
actionbazaar.persistence.User.class);
returnq.getResultList();

In this statement, the createNativeQuerymethod takes two parameters: the SQL query and the entity class
being returned. This will become an issue if the query returns more than one entity classwhich is why JPA allows
a @SqlResultSetMappingto be used with the createNativeQuerymethod instead of passing an entity
class. A @SqlResultSetMappingmay be mapped to one or more entities.
Here is an other example: Queries may return multiple objects and/or properties as an array of type Object[],
select mother, offspr, mate.name
from DomesticCat as mother
inner join mother.mate as mate
left outer join mother.kittens as offspr

or as a List (HQL specific feature)


select new list(mother, offspr, mate.name)
from DomesticCat as mother
inner join mother.mate as mate
left outer join mother.kittens as offspr

or as an actual typesafe Java object,


select new Family(mother, mate, offspr)
from DomesticCat as mother
join mother.mate as mate
left join mother.kittens as offspr

assuming that the class Family has an appropriate constructor.


We havent been able to find a corresponding set of examples in the EJB 3.0 book
The select clause picks which objects and properties to return in the query result set. If you list a set of columns,
they will be returned as an Object array for each row.

Page 17 of 35

You may also express queries in the native SQL dialect of your database. This is useful if you want to utilize
database specific features such as query hints or the CONNECT BY option in Oracle. It also provides a clean
migration path from a direct SQL/JDBC based application to Hibernate. Note that Hibernate3 allows you to specify
handwritten SQL (including stored procedures) for all create, update, delete, and load operations (please refer to the
reference guide for more information.)

Limitations of the Query Facility compared to Hibernate


There is no query construction API, like Hibernates Criteria objects.
We need to add more discussion of lazy vs. eager loading here. One reason why it doesnt get mentioned as much in
the JBoss material is that the session is typically always open, and so it is easy to fetch when needed. There is more
discussion about this in the Seam book.

Lifecycle of Beans
Beans, particularly session beans, have a lifecycle of being created, used destroyed, pooled, archived, recovered, etc.
A series of callbacks let you know what is happening.
As described above, the lifecycle of a session bean is very simple, as it has only two states: Does Not Exist and
Method-Ready Pool. The former is a default state when no such instance exists. The latter is when the instance has
been constructed (i.e., after class.newInstance(), injection processing, and running the @PostConstruct method if
present.

Bean Lifecycle Callbacks


A session bean has a lifecycle. This means that beans go through a predefined set of state transitions. If you've used
Spring or EJB 2, this should come as no surprise. If you haven't, the concept can be a little tricky to grasp.
To understand the bean lifecycle, it is important to revisit the concept of managed resources. Recall that the
container manages almost every aspect of session beans. This means that neither the client nor the bean is
responsible for determining when bean instances are created, when dependencies are injected, when bean instances
are destroyed, or when to take optimization measures. Managing these actions enables the container to provide the
abstractions that constitute some of the real value of using EJBs, including DI, automated transaction management,
AOP, transparent security management, and so on.

The Lifecycle Events


The lifecycle of a session bean may be categorized into several phases or events. The most obvious two events of a
bean lifecycle are creation and destruction. All EJBs go through these two phases. In addition, stateful session
beans go through the passivation/activation cycle, which we discuss in depth below. Here, we take a close look at
the phases shared by all session beans: creation and destruction.
The lifecycle for a session bean starts when a bean instance is created. This typically happens when a client receives
a reference to the bean either by doing a JNDI lookup or by using dependency injection. The following steps occur
when a bean is initialized:
The container invokes the newInstance method on the bean object. This essentially translates to a
constructor invocation on the bean implementation class.
If the bean uses DI, all dependencies on resources, other beans, and environment components are injected
into the newly created bean instance.

Message-Driven Beans
Message-driven beans are built on JMS, which is similar to TIB/RV. Most of the documentation provides a good bit
of background information on JMS and messages, including suggestions on when to use point-to-point and when to
use publish-and-subscribe.

Page 18 of 35

Some of the characteristics of JMS relative to TIB/RV are as follows:


JMS appears built on deployment-time defined subjects (or queues) which have names. The idea of using
names is similar to RV, though the names dont seem to have a dotted sequence of subject tokens for use
with wildcards, and the idea of defining all of the subjects at deployment time is quite different from the
dynamic behavior of TIB/RV.
The messages are hashmaps that have set of string, value pairs. This is similar to TIB/RV messages.
There are a variety of delivery protocols available, including point to point and queue, where the latter is
publish and subscribe.
Message-Driven Beans are identified using the @MessageDriven annotation, and can receive and send messages.
The information in the annotation specifies the subject and the protocol. This is an improvement over earlier
versions of the concept which puzzled me, because they subject name was in the XML configuration files, and the
not the Java code.

Interceptors
Interceptors are objects that interpose themselves on method calls or the lifecycle events of session and messagedriven beans. They allow you to encapsulate the common behavior that cuts across large parts of your application.
An example would be to add logging calls to each of your EJB classes.
EJB 3 interceptors implement Aspect Oriented Programming and solve this problem. In our example you simply
create a logging interceptor that does the logging, and you can make it the default interceptor for your application.
The logging interceptor will be executed when any bean method is executed. If the requirement for logging or
profiling changes, then you have to change only one class.

Specification and Example


The @Interceptors annotation allows you to specify one or more interceptor classes for a method or class. For
example, below we attach a single interceptor to the addLineItem method:
@Interceptors(ProfilingInterceptor.class)
public void addLineItem (...

The ProfilingInterceptor class would look like:


public class ProfilingInterceptor {
@AroundInvoke
public Object profile(InvocationContext ctx) throws Exception {
System.out.println("profile interceptor invoked");
long startTime = 0;
try {
startTime = System.currentTimeMillis();
return ctx.proceed();
}
finally {
System.out.println("Method " +
ctx.getMethod() + " executed in " +
(System.currentTimeMillis() - startTime) + "ms");
}
}
}

You can also apply the @Interceptors annotation to an entire class. When you do, the interceptor is triggered if
any of the target class's methods are invoked. For example, if the ProfilingInterceptor is applied at the class level as
in the following code, your logMethodEntry method will be invoked when the SalesOrderManager class's
addLineItem or addShipmentAddress method is called by the client:

Page 19 of 35

@Interceptors(ProfilingInterceptor.class)
@Stateless
public class SalesOrderManager implements OrderManager {
public void addLineItem (...
public void addShipmentAddress (...
}

The attachment can also be done through a deployment descriptor file in XML
<assembly-descriptor>
<interceptor-binding>
<ejb-name>SalesOrderManager</ejb-name>
<interceptor-class>
incra.util.ProfilingInterceptor
</interceptor-class>
</interceptor-binding>
</assembly-descriptor>

This would apply to the SalesOrderManager, but you could also indicate a * for all classes.

Other Uses
Not only can you interface method invocations, but you can also intercept EJB lifecycle events.

Transactions
First we define the features of ACID transactions.
Next, we focus on declarative transaction management. Using the TransactionAttribute type attribute, we can
declare a methods transaction rule as one of the following:
MANDATORY
REQUIRED
REQUIRED_NEW
SUPPORTS
NOT_SUPPORTED
NEVER
This information can be given in the annotation or in the XML file, and the annotation approach is suggested.
Pages 366 through 369 of the Burke and Monson-Haefel EJB 3.0 book defines each of the types listed above.
The propagation of transactions is a critical concept. The container implements chains of transactions.

Isolation and Database Locking


Moving on to a discussion of Isolation and Database Locking, we have the definitions of dirty, repeatable, and
phantom reads. Then a discussion of locks.
Optimistic locking is next discussed. This is controlled through the @Version annotation on a field that is a Java
long, typically called version.
Beans outside of the transactions scope provide a stateless service

Transaction Management Approaches


Explicit transaction management is available, but it is suggested that you not try to manage the transactions yourself.
The API used is called the Java Transaction API (JTA), which is very similar to the Hibernate sessions transaction

Page 20 of 35

management facilities. It is interesting that the Hibernate book has you performing transaction management, but this
indicates that the container is a stronger tool than the ORMapper.
Finally, the book talks about Exceptions and Transactions, and then conversational persistence contexts. These seem
like good ideas to try out as well.

The JNDI ENC and Injection


Every EJB container that is deployed in an application server has it own personal registry called the Enterprise
Naming Context (ENC).
What can be registered in the ENC?
references to interfaces
JMS queues or topics
JMS connection factories
Data sources
JCA resources
Etc.
The chapter has greatly expanded coverage of the JNDI, and combined with the facilities of Dependency Injection
from Spring.
The ENC can be populated from XML or from annotations.
There is a facility in EJB to inject references from the ENC. This allows you to place annotations on your class
members, marked with the annotation EJB, and the container will look up the name and inject the reference.

Security in EJB 3.0


This discussion is entirely new compared to the EJB 2 based sources that we used to use. The reason for the new
material is that now security can be described through declarative annotations on the various methods of the session
beans.
The chapter in Burke and Monson-Haefel (chapter 17) covers the login management facilities and JAAS.
For security, each type and method can have a @RolesAllowed method annotation attached. @PermitAll is the
default if not specified. If a RolesAllowed specification is given on a type, it applies to all methods unless
overridden. The permissions can also be located in an XML file,
In addition to specifying the roles that have access to an enterprise beans methods, the deployer can also specify the
runAs role for the entire bean. This role will be in effect for all methods executed within the specified method.
Most of the security features discussed so far have focused on declarative security, but there is also programmatic
security provided by two methods:
public interface EJBContext {
Principal getCallerPrincipal();
boolean isCallerInRole(String roleName);
};

It is up to the developer to implement calls to these to create a security policy.


There is little discussion in the chapter about how the roles are defined or associated with the user. Perhaps that is
implementation-specific.

Page 21 of 35

In the Seam framework, there are additional facilities for handling security, including an authenticate method which
can be defined, and an authentication component that is typically created via the component configuration facilities.

The Timer Service


The timer service can aid in managing scheduled tasks. For example, your business application may have to run a
daily report to determine inventory levels and automatically send out restocking requests. For most legacy
applications, it is typical to have a batch job to clean up temporary tables at the start or end of each day. The Unix
cron utility is probably the most popular and well-loved scheduling utility.
In JEE, the Timer Service is a wrapper over the Quartz package.
The EJB 3 timer service is based on the idea of time-delayed callbacks. The container invokes the timeout method
on your behalf when the time interval you specify elapses.
Example:

Web Services
Java EE 5 provides a robust platform on which you can build and deploy web services. Java EE 5 allows you to
build web services with either regular Java class (POJO) or EJB 3 stateless session beans. In this section we'll
briefly introduce the web services platform and then explain why you would choose EJB 3 session beans over
POJOs.

Standards
Specification

Purpose

Java API for XML Web Services 2.0 Platform specification


Java API for XML Binding 2.0

Binding for WSDL to Java

WS Basic Profile 1.1

Interoperability with .NET

Web Services Metadata 2.0

Metadata approach to define web service

Java API for XML RPC 1.1

Backward compatibility with J2EE 1.4 web services

In EJB 3, you define a web service with an annotation.


See also our document Notes on Web Services and Tools.

Page 22 of 35

Implementation of Web Services


Support for web services in EJB 3.0 is based on the Java API for XML-based Web Services (JAX-WS) 2.0
specification, as well as its predecessor, the Java API for XML-based RPC (JAX-RPC) 1.1. The reason for the name
change is to convey that web services are more than just RPC-like innovation.
JAX-RPC uses a <service-ref> deployment element in the EJB deployment descriptor, and a file that defines the
JAX-RPC mapping for the service. The mapping file is derived from the WSDL file for the service. The pieces in
the deployment include the WSDL file, the mapping file, and the webservices.xml file.
Web Services can be created using the @WebService annotation, which makes it easy to define and call one. These
are the JSR-181 annotations. These are similar to the Salesforce.com claim that any method in Apex Code can be a
web service with just one labeling annotation. Compared to the earlier efforts of defining deployments through
very-hard-to-construct XML files, this should make Web Service implementations much easier!
The implementation of JAX-WS in JBoss is based on the Apache Axis project, starting with JBoss 4.0.x.

Examples
package com.titan.webservice;
import javax.ejb.Stateless;
import javax.jws.WebService;
import javax.jws.WebMethod;
@Stateless
@WebService(name = "TravelAgent")
public class TravelAgentBean
{@WebMethod(operationName = "Reserve")
public String makeReservation(int cruiseId, int cabinId,
int customerId, double price) {
...
}
}

Broader Java EE Topics


EJB 3.0 and the behavior within the EJB container is just a part of the whole Java EE picture.

Servlets, JSP, and JSF


While EJB 3 is primarily designed to deal with server-side functionality, it has to be integrated with a front end at
some point in order for the whole application to do anything useful as far as an end user is concerned. We use the
terms presentation tier and web tier interchangeably.
One approach to running an EJB application is to write a client program that makes the calls to the Session beans.
However, a more common approach is to create a screen-based web application that uses Servlets.
The presentation side of a JEE web application is to use servlets combined with JavaServer Pages or JavaServer
Faces.
The presentation would typically be built from JSF components that have backing beans that fetch or send content to
the SessionBeans of the application. Commonly used servlet frameworks include Struts (see our document Notes
on Struts and Tiles), Spring MVC (see our document Notes on Spring), or JSF (see our document Notes on Java
Server Faces) or Seam (see our document Notes on JBoss Seam).

Java Mail
JEE 5 has Java Mail facilities. See our document Notes on Java Mail.

Page 23 of 35

Logging
See our document Notes on Java Logging.

Fitting the pieces together


Combining servlets with the EJB 3.0-based backend gives:

Deployment
To understand EJB packaging, you must consider how it fits into the bigger picture of Java EE packaging and know
what constitutes a complete enterprise Java application. Up to this point we have focused on using EJB components
such as session beans and MDBs to build business logic and JPA entities to implement your persistence code.
However, your application will not be complete without a presentation tier that accesses the business logic you built
with EJBs. Most likely, you've used standard technologies such as JSP or JSF to build the web tier of your
applications. These web applications, together with EJBs, constitute an enterprise application that you can deploy to
an application server.
To deploy and run an application, you have to package the complete application togetherthe web module and
EJBsand deploy to an application server. Usually you will group similar pieces of the application together in
modules. Java EE defines a standard way of packaging these modules in JAR files, and specifies the formats for
these JARs. One of the advantages of having these formats defined as part of the specification is that they are
portable across application servers.

Page 24 of 35

The table below lists the archives or modules supported by Java EE 5 and their contents. Note that each archive type
is used for packaging a specific type of module, such as EJB or web. For instance, a WAR is used to package a webtier application module, and the EAR file is intended to be the ber archive containing all the other archives so that
in the end, you're only deploying one file. The application server will scan the contents of the EAR and deploy it.
Type

Description

Descriptor

Contents

CAR

Client
application
archives

applicationclient.xml

Thick Java client for EJBs.

EAR

Enterprise
application
archive

application.xml

Other Java EE modules such as EJB-JARs.

EJBJAR

EJB Java
archive

ejb-jar.xml

Session beans, message-driven beans, and optionally entities.


Needs a persistence.xml if entities are packaged.

RAR

Resource
adapter 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.

To create these files, you can use the jar utility that comes with JDK. The final step is to assemble all the JAR files
into one EAR file for deployment. In 11.3.1 we show you a build script that creates a JAR file. Each of these JAR
types contains an optional deployment descriptor that describes the archive. As we have been discussing throughout
this book, you can use metadata annotations instead of a deployment descriptor.
In this section, we focus primarily on the EAR file and the EJB-JAR file, which contains the session and messagedriven beans, as well as entities. Your EAR file must have an application.xml file at the top level, which provides a
map of the contained pieces:

Page 25 of 35

The .ear file is created by running the jar utility provided in Java multiple times for the different layers, or (more
commonly) writing an Ant script that does that same thing. The Ant versions 1.6 and later have tasks for building
.war and .ear files.

EJB Best Practices


Most of this based on Chapter 21 of the Burke and Monson-Haefel EJB 3.0 book. The chapter is about real
world use, and it provides guidelines for evaluating container providers, for determining when to use entity and
session beans, etc.
The structure that the example creates for the travel agent system is quite applicable to trading systems, as follows:

Page 517 discusses whether or not to use EJBs. Situations where they are strong include:
Single and multi-system business transactions
Distributed functionality

Page 26 of 35

Portable components (not classes)


Applications relying on asynchronous messaging
Security roles
Persistence context management

Alternatives listed include Spring for the runtime framework, and Hibernate or iBatis for the persistence facilities.
The chapter says that JDO will be retired.

JBoss Workbook
Workbook 1: covers deployment configuration, directory structure, etc.
The directory structure of JBoss is:

The examples are organized as source code plus configuration information, and an ant script that handles build and
deployment. The ant script typically has targets like <defaulttask> (which does a compile and deployment),
compile, clean, and clean.db, and run.client.
Hypersonic is used as the database for JBoss by default.

Page 27 of 35

Workbook 2: for chapter 4: covering first beans


Some good programming examples, similar to those in the JBoss at Work book, except with a client program that is
not web-based. In this chapter, you create a client that interacts with a SessionBean called TravelAgent.
The domain object is Cabin, and the sessionBean is TravelAgentBean and TravelAgentRemote. The persistence.xml
file specifies that the Default Data source is to be used. This is located in the resources/META-INF directory.
The chapter also discusses how to use the JMX interface screen to start and stop the Hypersonic service, and to the
HSQL Database Manager to view contents of the db.
There are three parts to this chapter: the first uses the code from Chapter 4, the second uses JNDI bindings with
annotation to override the default JNDI binding, and the third uses a JBoss-specific XML deployment descriptor
(located in META-INF/jboss.xml).

Workbook 3: for chapter 5: covering the entity manager and persistence


Covers running examples of using persistence for complex objects such as the cruise/deck/cabin tree.
In these examples, we focus on the EntityManager, which is found using:
@PersistenceUnit(unitName=titan) private EntityManagerFactory factory;
@PersistenceContext(unitName=titan) private EntityManager manager;
We can then call the entity manager methods such as persist(), find(), and update(). Example 1 will create a Cabin,
and then update a field in the record. Example 2 shows the impact of transaction management, which indicates that
changing a field inside a transaction-scoped entity manager is different from a extended persistence context-scoped
entity manager. The third example shows different flush-mode behavior at the end of a transaction.
The next part shows how to use the JBoss/Hibernate persistence facilities outside of JBoss itself, as a standalone
client program.

Workbook 4: for chapter 6: covering writing the mapping information using


annotations
Covers using the different types of persistence annotations, testing each one through a client program that is
mapping information about customers, customertypes, and addresses to the database. The variations are:

Regular fields
@Id
@EmbbededId to map a primary key class to the database
Multi-table mapping
Embeddable classes

There is little that is new here for those of us who have used Hibernate outside of JBoss.

Workbook 5: for chapter 7: covering complex mappings such as


associations
More and more complex mappings and clients, including all seven of the relationship types. These are run in a
standalone program, rather than using JBoss itself. The topics are:
Cascading relationships
Inverse relationships
Lazy initialization
The domain objects used are: Ship, Cabin, Cruise, Customer, Phone, CreditCard, and Reservation.

Page 28 of 35

The primary one that gave us clarifying insights was inverse. Each relationship has an owning side. You must set
the information into the owning side for it to be persisted. For instance customer::creditCard is owned by customer.

Workbook 6: for chapter 8: covering mapping of inheritance relations


Set up the database for tables that have inheritance, try out the different modes.
The domain objects that are used are: Person, Customer, and Employee. The modeling approaches used are:
Single table per hierarchy.
Single table per class
JOINed inheritance strategy

Workbook 7: for chapter 9: covering queries


Quite a long one, as it goes through each of the ways to describe and execute queries, such as Criteria, etc. It is
based on a standalone client, which means that this program is almost identical to one that could be written for the
Hibernate book. The types of queries discussed include:
select
parameters
paging
IN
INNER JOIN
OUTER JOIN
DISTINCT
WHERE Clause
IS, LIKE
Aggregation and Group By
Section 9.2 covers Native SQL Queries, though we have tended to avoid such, and thus skipped over this section.

Workbook 8: for chapter 10: covering callbacks and events


This is a good one to carry out, since all of these concepts are relatively new.
10_1: For callbacks, we use a modified version of Customer, that has print statements in methods decorated with
@PrePersist, @PostPersist, and more.
Since these print statements are within the JBoss server process, they appear on the JBoss output console.
10_2: For events, we create a Listener class that gather all entity stats, and register it as a JMX bean. This is done
in the jboss-service.xml file. Run the client, then go to the JBoss JMX Management Console, find the bean, and
invoke its output() method.
However, neither of these workbook units provide much information about when you would want to use this
facility.

Workbook 9: for chapter 11: covering session beans


This chapter puts most of the pieces together regarding session beans in EJB 2.0 and EJB 3.0. The exercises here
show you how to build one of each.
Exercise 11_1: Stateless Session Bean: this is a simple payment processor, using annotations to register in the EJB
framework. It also has a configurable set of limits for validation, expressed as in-able resources
Exercise 11_2: XML Override: this uses XML to change the limits
Exercise 11_3: Annotationless Stateless Session Bean: this is the EJB 2.0 counterpart of the above

Page 29 of 35

Exercise 11_4: Stateful Session Bean: this is quite interesting example, as it maintains session on the server, but has
the client provide a dispatch loop to ask questions (queries) or make selections. In the example, you can query and
select the cruise, the ship, and the customer, then carry out a reservation. The annotations on the stateful bean are:
@Stateful
public class TravelAgentBean implements TravelAgentRemote {
@PersistenceContext(unitName="titan")
private EntityManager entityManager;
@EJB private ProcessPaymentLocal processPayment;
<methods go here>
}

Exercise 11_5: Annotationless Stateful Session Bean: this is the EJB 2.0 counterpart of the above. The XML file
looks like:
<?xml version="1.0"?>
<ejb-jar
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
version="3.0">
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<remote>com.titan.travelagent.TravelAgentRemote</remote>
<ejb-class>com.titan.travelagent.TravelAgentBean</ejb-class>
<session-type>Stateful</session-type>
<remove-method>
<bean-method>
<method-name>bookPassage</method-name>
</bean-method>
<retain-if-exception>false</retain-if-exception>
</remove-method>
<ejb-local-ref>
<ejb-ref-name>ejb/PaymentProcessor</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>com.titan.processpayment.ProcessPaymentLocal</local>
<injection-target>
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>processPayment</injection-target-name>
</injection-target>
</ejb-local-ref>
<persistence-context-ref>
<persistence-context-ref-name>
persistence/titan
</persistence-context-ref-name>
<persistence-unit-name>titan</persistence-unit-name>
<injection-target>
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>entityManager</injection-target-name>
</injection-target>
</persistence-context-ref>
</session>
</enterprise-beans>
</ejb-jar>

Which is another way of declaring the stateful session bean called com.titan.travelagent.TravelAgentBean.

Page 30 of 35

Workbook 10: for chapter 12: covering message-driven beans


The example is similar to the above client program except that the sender is now using JMS queues, and the beans
are message-driven. The beans also send out messages on another queue. Also, you need to deploy the JMS queues
before anything else. These queues have names such as titan-ReservationQueue and titan-TicketQueue. These are
defined through the following files:
<server>
<mbean code="org.jboss.mq.server.jmx.Queue"
name="jboss.mq.destination:service=Queue,name=titan-ReservationQueue">
<depends optional-attribute-name="DestinationManager">
jboss.mq:service=DestinationManager
</depends>
</mbean>
<mbean code="org.jboss.mq.server.jmx.Queue"
name="jboss.mq.destination:service=Queue,name=titan-TicketQueue">
<depends optional-attribute-name="DestinationManager">
jboss.mq:service=DestinationManager
</depends>
</mbean>
</server>

The program that receives the completed reservations is called the consumer, and it is to be run in a different
window.
The server bean that is listening simply has a @MessageDrvien annotation attached, as follows:
@MessageDriven(activationConfig={
@ActivationConfigProperty(propertyName="destinationType",
propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination",
propertyValue="queue/titan-ReservationQueue")})
public class ReservationProcessorBean implements javax.jms.MessageListener {
@PersistenceContext(unitName= "titan")
private EntityManager em;
@EJB
private ProcessPaymentLocal process;
@Resource(mappedName="java:/JmsXA")
private ConnectionFactory connectionFactory;
public void onMessage(Message message) {
System.out.println("Received Message");
}
}

This indicates that it is subscribing to queue/titan-ReservationQueue, and is receiving messages.

Workbook 11: for chapter 13: covering the Timer Service


This is a pretty simple example, as all it involves it having a session bean start a timer sequence so that a new
request appears five seconds later.

Workbook 12: for chapter 15: covering Interceptors


The specific use is profiling interceptors.
15.1: EJB interceptors: this example extends the command-line driven test from 11.4. After you have made a
reservation, check the JBoss log for an entry about the bookPassage() method being called.
There is an interceptor specified on the bookPassage method, which request that the following be run:
package com.titan.interceptors;

Page 31 of 35

import javax.ejb.*;
import javax.interceptor.*;
public class Profiler {
@AroundInvoke
public Object profile(InvocationContext invocation) throws Exception {
long startTime = System.currentTimeMillis();
try {
return invocation.proceed();
}
Finally {
long endTime = System.currentTimeMillis() - startTime;
System.out.println("Method " + invocation.getMethod()
+ " took " + endTime + " (ms)");
}
}
}

15.2: Intercepting EJB callbacks: implements the @JndiInjected custom injection annotation discussed in chapter
15. This is not quite as interesting, as it runs during deploy time or load time, rather than runtime.

Workbook 13: for chapter 16: covering Transactions


While the chapter is quite long, the workbook only shows one example of how to use transactions, in this case to
implement conversational persistence contexts (which is an important concept in Hibernate, Seam, and EJB 3.0).
The example is only about 2 pages long, and is a variation on the commandline-driven reservation system, but it
now supports multiple reservations by TravelAgentEJB. The CruiseCabin entity described in the Optimistic
Locking section of chapter 16 is incorporated into the example.
The purpose of the exercise is to show how entity manager operations are queued until the persistence context
becomes associated with a transaction at which point it will be committed.

Workbook 14: for chapter 17: covering Security


This would be a good one to carry out, but we spend most of our time on programmatic security.
17.1: Using JBoss security. First we configure JBoss security by defining a security policy which uses the login
module and two properties files. The client program is similar to those shown earlier, but has @SecurityDomain
@RolesAllowed() and @PermitAll annotations on some methods.
The example uses the command-line shell again, with a login step at the beginning. If you try to carry out an
operation that is not permitted within the security specifications, you will get a javax.ejb.EJBAccessException.
17.2: This is similar, but uses an XML file for the security specifications rather than annotations.

Workbook 15: for chapter 19: covering Web Services


19.1: Exposing a stateless bean: the ant script builds and deploys two jar files, a server file and a client file. The
TravelAgentBean is in the server, and has been annotated with @WebService and @WebMethod annotations. This
enables JBoss to construct the wsdl file, which can be read at
http://localhost:8080/titan?wsdl
The example starts with use of JAX-RPC, which means that the JAX-RPC mapping file is used. Actually, what the
author is doing is showing how to use JAX-WS on the server side, and showing compatibility with the earlier JAXRPC by calling the server with a JAX-RPC client. This didnt work due to some difference between JBoss 4.0.x and
4.2.x, so we converted the client over to using JAX-WS, as well as updating to JAX-WS 2.0.3.

Page 32 of 35

Running the client code produces the same output as in exercise 4.1, because it is also setting up one cabin row in
the database. However, the client is running a web service invocation to trigger the processing. There are two
primary files that make up the client. The first defines the service, with annotations:
package com.titan.travelagent;
import
import
import
import

javax.jws.WebMethod;
javax.jws.WebParam;
javax.jws.WebResult;
javax.jws.WebService;

import com.titan.domain.Cabin;
@WebService(name="EndpointInterface",
targetNamespace="http://localhost:8080",
serviceName = "TravelAgent")
public interface TravelAgentService {
@WebMethod @WebResult(name="Cabin")
public Cabin findCabin(
@WebParam(name="id")
int id);
@WebMethod
public void createCabin(
@WebParam(name="cabin")
Cabin cabin
);
}

The second is the client itself:


package com.titan.clients;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import com.titan.domain.Cabin;
import com.titan.travelagent.TravelAgentService;
public class Client {
public void doTest(String[] args) {
try {
URL wsdlURL = new URL("http://localhost:8080/titan?wsdl");
QName serviceQName = new QName("http://localhost", "TravelAgentService");
Service remoteService = Service.create(wsdlURL, serviceQName);
TravelAgentService agent =
(TravelAgentService) remoteService.getPort(TravelAgentService.class);
Cabin cabin_1 = new Cabin();
cabin_1.setId(1);
cabin_1.setName("Master Suite");
cabin_1.setDeckLevel(1);
cabin_1.setShipId(1);
cabin_1.setBedCount(3);
agent.createCabin(cabin_1);
Cabin cabin_2 = agent.findCabin(1);
System.out.println(cabin_2.getName());
System.out.println(cabin_2.getDeckLevel());
System.out.println(cabin_2.getShipId());
System.out.println(cabin_2.getBedCount());

Page 33 of 35

} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
client.doTest(args);
}
}

19.2: Using a .NET client


Not relevant

Workbook 16: the class loader


JBoss class loading scheme is similar to the strategy used by other J2EE application servers, as shown below:

Common class loader issues:


Not enough visibility a jar or directory is not available

Page 34 of 35

NoClassDefFoundError one additional reason is that a class can depend upon another class which cannot
be found
Too much visibility there may be duplicate classes

Solving issues:
Know the basics of ClassLoaders and how your particular deployment environment uses them.
Make sure there are no duplicate classes or JAR files
Encapsulate/Minimize Visibility to avoid ClassCastException
Use the correct ClassLoader. Use the ThreadContext ClassLoader.

Workbook 17: JBoss Database Connection Setup


This section describes the organization of connection information (very similar to Hibernate configuration files) and
where to store it in the JBoss environment.

Open Issues
Assuring scalability (this implies setting up efficient database schema, using multiple servers, managing clusters) is
only partially covered in the material we have read so far.
Assuring fault-tolerance (this implies setting up hot standby severs) is not covered at all in the material read so far.
We think that it is in the JBoss in Action book.

Page 35 of 35

Vous aimerez peut-être aussi