JEE6 Tutorial
31 Dec 2012

I hereby start a series of tutorial on the major (IMHO) JEE 6 features. As a lecturer, I teach the JEE stack at the University of Geneva. This tutorial represents most of the topics that I cover during the EJB, CDI, and JPA lessons.

As the EJB 3.1 specification is rather well written, I encourage people to read it or at least to look at specifics when needed.

To support this tutorial you can find a JEE6-Demo on GitHub. It contains a simple enterprise application that demonstrates many of the
aspects I discuss hereafter. The first step of this tutorial is to prepare the environment:

1) Install GlassFish and integrate it to your favorite development environment (eclipse in my case). You can get GlassFish from here. Grab the zip version and install it by unzipping the archive.

2) Run GlassFish and check that it works. Locate the script named asadmin in the bin directory, start it and at the prompt, execute the command start-domain. This starts the GlassFish instance.

Now that the database is started. It is time to populate the database with the database creation scripts as well as some data.
In the project, under the ejb components, there is a sql file that initializes the database structure as well as some data.

Derby provides a command line tool called ij to connect to the database and to execute sql scripts:

The connection pool provides a … pool of connection that is managed by the application server. A major benefit being that the developer does not have to open and close connections.
The server opens n connections and allocate them on demand. It ensures that there will not be 1000 open connections to the database thus improving the performances.
Then, we create a datasource that uses the previous connection pool:

The tutorial is organized in three parts. First, in this post, we will look at the EJB stack. In following posts, we will cover both the Context and Dependency Injection and the Java Persistence API.

EJBs

The EJB API provides useful non-functional services to Java Enterprise Applications such as transactionality, security, pooling, and thread-safety.
Server side components that implement this API and wrap up business logic are called Enterprise Java Beans (EJBs). While the first versions were infamously known for the boilerplate code as well as their low testability,
EJB 3.x are rather easy to use thanks to a new design paradigms called Convention over Configuration. The idea is to specify unconventional aspects rather than everything. This dramatically reduces the boilerplate code and improves readability.

Furthermore, the massive usage of annotations instead of XML descriptor greatly improves the productivity. In the sequel, I mostly rely on annotations. Nevertheless, every annotation has its counterpart in a configuration descriptor that is called ejb-jar.xml.

In case there is two different value for the same property, remember that one from the ejb-jar.xml always overrides the annotation.

Enterprise Java Beans are of three kinds:

Session Beans: components whose execution is triggered by a client call. The call can be local (within the JVM) or remote (by another JVM).

Message Beans: execution is triggered by a message and the business logic is processed asynchronously. Please note that, since JEE6 there are other (simpler) ways to process logic asynchronously. Nevertheless, Message Beans
remain very useful to implement bus and/or publish-subscribe patterns and to enforce loose coupling between the client and the server component.

Session Beans

As mentioned previously, session beans (merely) react on client invocation. Henceforth, the bean can either take the client session into account (thus it shares a state between multiple client invocations) or it can treat each call as unrelated.
In the first case, the EJB is called Stateful while in the latter it is called Stateless.

Stateless Session Beans

Let us start with a Stateless bean. The following Java class describes a Stateless EJB.
The most important part is the annotation @Stateless at the top of the class.
This marks the class as an EJB. When the container instantiates this class, it knows that
it is a so-called Managed Bean. By this, it means that the container manages the bean’s lifecycle (e.g., instantiation, passivation). Furthermore, as an EJB, it has access to the container services such as security and transactionality.

The following snippet describes a Stateless Session bean that computes a grade distribution. The method is secured and only authorized to client that have the role user through the @RolesAllowed({ "user" }) annotation.

@StatelesspublicclassStudentServiceJPAImplimplementsStudentService{...@Override@RolesAllowed({"user"})// This a role-based security.publicfinalInteger[]getDistribution(finalintn){numberOfAccess++;Integer[]grades=newInteger[n];for(Students:this.getAll()){grades[(s.getAvgGrade().intValue()-1)/(TOTAL/n)]++;}returngrades;}...}

Please note that the previous EJB implements an interface. An EJB can be local (invokable from within the container),
remote (invokable from another JVM) or both. In the previous case, it is a local interface and therefore the bean is only
invokable locally.

@LocalpublicinterfaceStudentServiceextendsSerializable{/**
* @return an array that contains the distribution of the grades. It
* partitions the grades in "n" parts.
* @param n : number of parts
*/int[]getDistribution(finalintn);}

Adding a remote invocation to the implementation amounts to add an interface that is annotated @Remote.
Of course, the interface may be different and may exposes different services locally and remotely.

@RemotepublicinterfaceStudentServiceRemoteextendsSerializable{/**
* @param lastname
* of the student
* @return the student with the given lastname.
*/StudentgetStudentByLastName(Stringlastname);}

The implementation must be changed as follow to be remotely invokable:

To use this EJB, we need a client code. The easiest possible interaction is either via a JAX-RS service or via a servlet.
In the JEE6-Demo, under the JEE6-WEB project the JAX-RS facade is called StudentFacade.java. It implements a JAX-RS facade over the StudentService.

The method getDistribution() uses the student service that is injected via @EJB in the
facade. Dependency injection is now a first class citizen in the JEE6 stack.

@ApplicationScoped// This sets the scope to application level@Path("/studentService")publicclassStudentServiceFacadeimplementsSerializable{...@EJBStudentServicestudentService;@GET@Produces({"application/xml","application/json"})@Path("distribution")publicResponsegetDistribution(){Integer[]distrib=studentService.getDistribution(10);returnResponse.ok(newDistributionDto(distrib)).build();}}

The following snippet illustrates the injection of a Stateless EJB into a Servlet.

As you can see, implementing EJBs (and invoking them) is rather easy. So far, we did not talk much about transactionality and security so you might wonder why using EJBs for such simple business services. The answer is pooling and thread-safety. As the container manages a pool of EJBs, it handles the invocation queue and you do not have to manager re-entrance and thread-safety.

Remember that there is a one to many relationship between a stateless session bean and the clients. In other words, one instance may manage different clients. Hence, there must be not field that represent a client state in a Stateless EJB because there is no guarantee that a given client will get the same SLSB accross two invokations. Nevertheless, within a given invokation the client is guaranteed to be the only user.

Consider the following exercises.

Exercise 1: Add a new method to the StudentService service that computes the standard deviation and use this method in the JAX-RS facade.

Exercise 2: Add a counter that is incremented each and every time a method is invoked. Print out the thread-id (and if possible the session-id) and explain why the so-called stateless beans must be without state. Add a rest service to interface this method.

Transactionality

Transactions are important concepts when dealing with enterprise applications. It is of vital importance that whenever something goes wrong, the transaction is roll-backed. This preserves the ACID properties. Managing database transactions with JDBC is complex to say the least. Remember that we often have to manage transactions over several databases and even between databases and messaging queues. If the processing of a message leads to a database exception, we might want to put the message back in the queue.

Lucky for us, JEE 6 manages (almost) everything by itself. By default a bean is transactional and each method either reuse a running transaction or creates a new one if necessary.

By default the transaction (or transaction context) is propagated to other business methods that are called from within a transactional method.

In JEE, there is two types of transaction management:

Bean Managed : In this case the bean is annotated with @TransactionManagement(TransactionManagementType.BEAN). In this mode, the developer must manage the transaction himself.

Container Managed: this is the default behavior and it corresponds to marking the bean @TransactionManagement(TransactionManagementType.CONTAINER). This mode is called Container Managed Transaction Demarcation. This idea is that every public method is transactional and is marked as @Required.

Because the previous snippet relies on the default convention, it is equivalent to:

@MessageDriven(mappedName="MyQueue")@TransactionManagement(TransactionManagementType.CONTAINER)@TransactionAttribute(TransactionAttributeType.REQUIRED)publicclassStudentRegistrationServiceimplementsMessageListener{@Inject// Let's ignore this for the momentprivatetransientLoggerlogger;@PersistenceContextEntityManagerem;@Resource// Let's ignore this for the momentprivateMessageDrivenContextmdbContext;publicvoidonMessage(MessageinMessage){TextMessagemsg=null;try{...msg=(TextMessage)inMessage;logger.info("MESSAGE BEAN: Message received: "+msg.getText());logger.info(Thread.currentThread().getName());...}catch(JMSExceptione){em.getTransaction().rollback();...}}}

In other terms, it uses container managed transaction demarcation @TransactionManagement(TransactionManagementType.CONTAINER).
Moreover, each and every public method either reuses an existing transaction or creates a new one if none has been started @TransactionAttribute(TransactionAttributeType.REQUIRED)

The @TransactionAttribute annotation can also be put directly on the method. Valid options are:

REQUIRED: if there is an existing transaction then it reuses it, otherwise it creates a new one.

REQUIRES_NEW: it always creates a new transaction

NEVER: if there is an existing transaction then it fails

MANDATORY: if there is an existing transaction then it reuses it, otherwise it fails

NOT_SUPPORTED: If there is a transaction then it suspends it and it does not propagate the transaction to other business methods, otherwise it does nothing.

SUPPORTS: If a transaction exists then it works as for REQUIRED, otherwise it works as for NOT_SUPPORTED.

Consider the following exercises.

Exercise 3: Test the different types of transaction attribute and observe their respective behavior.

Exercise 4: Are the snippets 1 and 2 semantically equivalent?

Exercise 5: Mix the two types of transaction management.

Security

Another great feature of EJBs is their ability for declarative authorization and the integration in the JAAS framework. JAAS is the Java Authentication and Authorization Service
It provides unified services to access user directories for user authentication and their authorization. As the client is already authenticated, at the EJB level, only authorization matters.

After authentication, a principal (e.g., user name, role) is set in the context. This principal is used for authorization.

The main annotation is @RolesAllowed followed by a list of authorized roles. As an example, look at the method getDistribution of StudentServiceJPAImpl.java. The method is only allowed for client that belongs to the group/role user.

Sometimes, a method of an EJB is not executed in the context of an authenticated user or the authenticated user has not enough credentials. If it is still important to run the method, you can use the @RunAs annotation. This basically overrides the current security context (and the associated principal) similarly to sudo for UNIX.

In any EJB, it is possible to get the current client session and therefore the principal:

@ResourceSessionContextctx;publicvoiddoSomething(){// obtain the principal. Principalprincipal=ctx.getCallerPrincipal();// obtain the name. Stringname=callerPrincipal.getName();// Is the caller an admin?ctx.isCallerInRole("admin")}

Exercise 6: Change the method getDistribution to only allow client that belong to the admin group. Log as a user and as an admin, check the servlet as well as the JAX-RS service. What do you observe?

Exercise 7: Add a new Role to the application, and use it. Warning, some configurations are vendor specific.

Exercise 8: Create a service that uses @RunAs to upgrade the credentials of a standard user in order to call another service that requires the admin level.

Callbacks and Interceptors

Interceptors are used to enhance the business method invocations and the beans’ lifecycle events. Interceptors implements the AOP paradigm.

Interceptors are of two kinds:

Lifecycle event interceptors such as @PostConstruct, @PostActivate, and @PrePassivate, and @PreDestroy enable to add logic when the bean is created or destroyed.

Call-based interceptors that relies on the @AroundInvoke annotation.

In the first case, adding the annotation before the method declaration is enough. It will then be called when the lifecycle event occurs.
In the latter case, in addition to the annotation the developer must configure the ejb-jar.xml file.

Here is a simple interceptor that prints out the time consumed by a method call:

In addition to the interceptor declaration, it must be activated by mean of either an annotation on the target EJB or via the ejb-jar.xml file. If several interceptors are declared, then the order of declaration is the order of execution: the last is the most nested interceptor.

In the following snippet, the interceptor is applied to all methods whose name is like get* and EJB’s name is like Student*. It is also possible to specify the parameters’ type in case of overloading.

<assembly-descriptor><!-- Default interceptor that will apply to all methods for all beans in deployment --><interceptor-binding><ejb-name>Student*</ejb-name><method><method-name>get*</method-name></method><interceptor-class>ch.demo.business.interceptors.PerformanceEJBInterceptor</interceptor-class></interceptor-binding>
...
</assembly-descriptor>

Exercise 9: Add an interceptor that for all public methods of StudentServiceJPAImpl.java to increments an overall (common to all clients) usage counter using the annotation based approach.

Exercise 10: Do the same, but using the ``ejb-jar.xml`.

Timers

Some services are not directly linked to a client session. This is the case for batch processes that must run every x hours. To that end, EJB 3.1 provides the annotation @Schedule to specify how often a service method must be called. This is similar to the CRON feature on UNIX systems.

The following example runs the method doSomethingUseful every 30 minutes.

@Schedule(minute="*/30",hour="*")publicvoiddoSomethingUseful(){...}

Exercise 11: Add a scheduler that runs a method every minutes to print out the number of students in the database.

Exercise 12:@Schedule is often used in conjunction with @RunAs. Why?

Asynchronous calls

Asynchronous calling means that the control is returned to the caller before the process has been completed. For instance, a batch job that loads 1000 customers description from one database, processes them and finally save them in another database. From a performances point of view, it is better to split the process in x batches and then to wait until every thing is finished. Firstly, if the asynchronous call is made to another EJB, it is possible to leverage the pool to have parallel treatments without managing multi-threading and race conditions. Secondly, as the different call may use different database connections, it will limit the database bottleneck.

To do this, JEE provides the @Asynchronous annotation. Any method that returns either nothing (void) or an instance of type Future<T> can be run asynchronously.

The Future interface exposes the method get that blocks until the job is over.
The following class, exposes the method processJob that runs asynchronously.

The methods processJobs starts 10 times the method processJob and put the resulting Future<String> in an array. Then it iterates of the pool and wait until all calls have returned.

Exercise 13: Create an EJB that invoke an asynchronous method that runs 100 times. The asynchronous method should wait a random time between 5 and 10 seconds before returning a the actual waiting time. Collect all the waiting times and compute the average.

Singleton Beans

Singleton beans (@Singleton) are special kind of EJBS that exist only in one instance in the container. This is for instance useful to initialize the application. Thus, @Singleton can be associated with @Startup to start the EJB during container’s startup.

As there is only one instance, it means the bean is meant to be shared. Therefore, it is important to specify the locking policy. There are two types of locking:

Container managed concurrency management @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER). This is the default behavior and it is highly recommended to stick to it. Annotating a method (or the class) with @Lock(LockType.READ) means that the method can be safely access concurrently. @Lock(LockType.WRITE) requires the calls to the method to be serialized. The methods are @Lock(LockType.WRITE) by default.

Bean managed concurrency management @ConcurrencyManagement(ConcurrencyManagementType.BEAN). This requires the developer to use synchronized and volatile to achieve good concurrency.

By default the class is marked as @Lock(LockType.WRITE), thus EVERY CALL is synchronized. This is probably not the expected behavior (at least most of the time) and produces a huge bottleneck. Make sure to set the proper lock policy on the class and to only put @Lock(LockType.WRITE) where needed.

The following bean initialize a shared variable during container startup and lock the access to the modification to only one thread (client) at a time.

Exercise 14: Write a singleton that reads the postal code from the database during startup, update them every 30 minutes. Take care of the concurrency aspects.

Stateful Session Beans

Unlike stateless session beans, stateful session beans maintain a state across several client invocation. This is because there is a one to one relationship between a client and a stateful session bean.

The following code snippet describes a stateful session bean that maintains a counter across several invocations.
A stateful session bean is annotated with @Stateful. As it is stateful, it maintains a session state and it is therefore important to set a timeout. Otherwise, the number of open session will raise and it will consume the server memory.
The timeout is defined using the @StatefulTimeout annotation.

Because there is no instance sharing among several client, Stateful session beans are more resource-demanding than stateless session beans. Therefore, they should be used with great care.

@Stateful@StatefulTimeout(unit=TimeUnit.MINUTES,value=30)publicclassStudentStatisticsServiceImplimplementsStudentStatisticsService{privateLongnumberOfAccess=0l;@OverridepublicStringgetStatistics(){return"The student service has been invoked #"+numberOfAccess+" in this session";}publicvoidcount(){numberOfAccess++;}}

As a stateful session bean is not per se linked to an HTTP session, the application client code must ensure to remember which instance of the EJB is dedicated to which client.
When used in conjunction with a Servlet, Stateful beans are often put in the HTTP session for further reuse.

@OverrideprotectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{StudentStatisticsServicestatistics=(StudentStatisticsService)request.getSession().getAttribute(StudentStatisticsService.class.toString());if(statistics==null){try{InitialContextctx=newInitialContext();statistics=(StudentStatisticsService)ctx.lookup("java:global/JEE6-EAR/JEE6-EJB-0.0.1-SNAPSHOT/StudentStatisticsServiceImpl");request.getSession().setAttribute(StudentStatisticsService.class.toString(),statistics);}catch(NamingExceptione){thrownewRuntimeException(e);}}statistics.count();response.getOutputStream().println("There are #"+studentService.getAll().size()+" students in the database");response.getOutputStream().println(statistics.getStatistics());response.getOutputStream().println(studentService.getStatistics());}

Either the EJB is looked-up with JNDI and then put into the HTTP session or, when using CDI, the link is made based on the caller scope.
The class StudentServiceFacade.java describes how the injection automatically links the correct instance of a stateful session bean to a given based on the @SessionScoped annotation.

Exercise 15: Show that two sessions share the same overall count but not the same per session count.

As the container does not share the stateful instances, it might run out of memory and therefore it will try to save the state of the bean on disk (or database). This operation is called Passivation. Afterwards, when the client comes back and requires its stateful instance, the container loads it from the disk. This operation is called Activation.

Some operations such as initializing/cleaning File, a socket connection, or a database connection can be made before activation and/or after activation using the following
@PrePassivate and the @PostActivate annotations.

Consider the following exercises:

Exercise 16: Stop the server and observe that the bean has been passivated.

Exercise 17: Start the server and observe that the bean has been activated.

Whenever the user logs out and thus invalidate the HTTP Session, you might want to clean up the EJB state and release the resources. To achieve this, the client must call a method annotated with @Remove. As soon as the client call is over the container can garbage the bean. The idea is simply to get ahead of the timeout.

Exercise 18: Implements two methods with @Remove with two different behaviors. Check that both will discard the current instance. Hint: you can use @PreDestroy to check the bean’s destruction.

Message Driven Beans

Message driven beans (MDB) are very useful for asynchronous process and for decoupling the client from the processor. MDB implement a typical publish/subscribe architecture.

There are two kinds of objects, a MDB can listen to:

Topics: pure publish/subscribe semantics. A new message will be processed by every listeners.

Queue: more of a load balancer, once the message is consumed by one of the listeners, it
is removed from the queue.

Although, there is, in JEE6, another mechanism for asynchronous processing, MDBs remain the best alternative if you do not want the client to be aware of the asynchronous logic and processor.

The idea is that there is a queue (or a topic) in between. Therefore, the client as no knowledge whatsoever of the message processor contract or semantics.

The first step is to configure a Queue Connection Factory as well as a Queue in the application server.

The following servlet gets the connection factory as well as the queue injected. As always with dependency injection, the same result can be achieved using JNDI lookups.
For each request to the servlet 100 messages are generated and put in the Queue called MyQueue.