ONJava.com    
 Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples


What's New in EJB 2.1?

by Emmanuel Proulx
08/14/2002

Who said the JPC is slow?

Only a few J2EE application servers are following the EJB 2.0 specification, and already the EJB 2.1 draft specification is out. For you busy folks who want to know about what the future has in store for EJBs but don't have the time to read a 636-page document, here is a quick overview. Fair warning: the specification is a draft, so many parts are incomplete or will change.

Quick List of New Features

Message-driven Bean Enhancements

When the EJB 2.0 specification appeared, it introduced the idea of calling an EJB asynchronously, but you had to do it with JMS. JMS is not the only way to invoke an object asynchronously, however; other APIs exist, such as JAXM. How is this done with EJB 2.1?

Related Reading

Enterprise JavaBeans
By Richard Monson-Haefel

There are two things that differ. First, as you may know, in order to write an MDB class, it must implement some interfaces. These are javax.ejb.MessageDrivenBean and javax.jms.MessageListener. The latter is the interface that enables the EJB container to subscribe the bean to the JMS server. To make your EJB listen to another type of messaging server, the MDB must implement another interface. For example, in order to listen to JAXM messages, the MDB must implement javax.xml.messaging.OneWayListener or javax.xml.messaging.ReqRespListener.

As for the second difference, obviously, the configuration side of a JMS-MDB will differ from a non-JMS one. The EJB container must know which destination or endpoint to which it must connect. The configuration of the MDB is done with a new <messaging-type> tag, and by specifying "configuration properties" with the tag <activation-config-propertyType>. This contains arbitrary name/value pairs that are specific to the messaging service being used. It is more versatile than being forced to use JMS-specific tags, like <message-selector>.

The way non-JMS servers will plug into the EJB container is more or less overlooked in the current draft version of the specification. There is a mention of using the J2EE-CA, but no details are provided. This will probably be left to the EJB container to implement, just like persistence services.

EJB-QL Enhancements

When EJB-QL came out as a standard way to write queries, it was criticized for being a reinvention of the wheel. Don't we have already some querying languages, like SQL and XQuery? Plus, EJB-QL lacks several features that made it less than useful, in some cases. EJB 2.1 is trying to remedy these problems by extending the language to make it more SQL-like. Here are a few clauses and functions that are now added to this language.

ORDER BY

Ordering is something that's usually more optimized when it's done by the database than when it's done on the client side. This new clause simply works by specifying which fields to sort on, and if data needs to be sorted in ascending or descending order. For example:

SELECT OBJECT(c) FROM ConsultantBean AS c ORDER BY c.city,c.startingDate DESC

returns all consultants sorted by city, starting with the most senior.

MOD

This numeric function returns the rest of the division between an integer and another integer (modulo). For example:

SELECT OBJECT(p) FROM PageBean AS p WHERE MOD(p.number,2) = 1

returns all odd-numbered pages.

AVG

AVG is an aggregate function that can be used for ejbSelect methods in the SELECT clause. It returns the average value of a specified field. For example:

SELECT AVG(e.salary) FROM EmployeeBean AS e

gets the average salary for all employees.

MIN

This aggregate function can be used for ejbSelect methods in the SELECT clause. It returns the minimum value of a specified field. For example:

SELECT MIN(f.nextFlightDate) FROM FlightBean AS f WHERE f.departureAirport = ?1 AND f.arrivalAirport = ?2

gets the date when the next flight is scheduled between two cities.

MAX

This aggregate function can be used for ejbSelect methods in the SELECT clause. It returns the maximum value of a specified field. For example:

SELECT MAX(c.age) FROM ClientBean AS c

returns the age of the oldest client.

SUM

This aggregate function can be used for ejbSelect methods in the SELECT clause. It adds up all values for a field. For example:

SELECT SUM(q.sales) FROM QuarterBean AS q WHERE q.year = ?1

calculates the total of all sales for a certain year.

COUNT

This aggregate function counts the number of elements. It can only be used in ejbSelect methods and in the SELECT clause. For example:

SELECT COUNT(s) FROM StoreBean AS s WHERE s.city = ?1

counts the number of stores in a certain city.

About Aggregate Functions

The aggregate functions (AVG, MIN, MAX, SUM, and COUNT) can be used with DISTINCT to eliminate duplicates before calculating.

Personally, I don't see why all of these aggregate functions cannot be used in the WHERE clause, as well. The specification says these can be used in the SELECT clause only. It could be useful to test each record against a condition that uses an aggregate function. For example, getting all employees whose salary is above average:

SELECT OBJECT(e) FROM EmployeeBean AS e WHERE e.salary > AVG(e.salary)

One can work around this with an ejbSelect method, or in other ways.

Web Services

One of the best features of EJB 2.1 is the support for Web services. This applies to two different areas: accessing an EJB as if it were a Web service, and an EJB directly accessing a Web service.

EJB As Web Service

A stateless session EJB can now be accessed through a Web service. In order to do that, the client must use SOAP over HTTP or HTTPS, and use a WSDL descriptor. Furthermore, the stateless session bean must be invoked "RPC-style." To help with the development of Web-service-enabled beans, the specification was changed in these ways:

Forcing the use of HTTP is somewhat restrictive, since Web services are supposed to accept any protocol and technology, but this follows the general trend. By spelling out these restrictions, though, I think we will get into the same trap as JMS-only message-driven beans. The specification will later have to change to accommodate more standards.

Many people have pointed out the disconnection between what exists in the Web service realm and what is available in EJBs. Here are a few examples:

While these things are not addressed in the specification, they are not addressed in SOAP, either. There are programmatic solutions around those limitations, and it will be up to the container providers and/or bean developers to invent these solutions.

EJB Accessing a Web Service

An EJB can directly access a Web service, simply as a regular Web service client does. But this means the Web service's location has to be hard-coded in the bean implementation's code. This is not ideal, because if the Web service moves to a new location, the EJB must be modified and recompiled. To work around this problem, the new EJB 2.1 specification introduces the concept of a Web service reference. This is exactly the same concept as environment entries, EJB references, and resource references. Adding a Web service reference in ejb-jar.xml is done using the new tag <service-ref>. It is up to the container provider to map the reference to the actual Web service location. The reference can be looked up in the bean implementation, and the resulting factory object can be used to connect to the Web service.

EJB Timer Service

The new EJB 2.1 timer service is a mechanism to enable time-based business logic. For example, one could want to automatically:

Note that this timer service is not meant to be used in real-time systems. Notifications will be sent at approximate times.

To set up a timer object, use the method EJBContext.getTimerService(), returning a javax.ejb.TimerService object. This object is a factory for creating javax.ejb.Timer objects. Once such an object is created, the container will take care of calling the bean at the right time. Timer objects can later be retrieved using the TimerService object or with a TimerHandle (Serializable), and they can be cancelled and reconfigured.

Only "stateless" objects (stateless session beans, pooled entity beans) can process timer events. Their bean implementations must implement the javax.ejb.TimedObject interface, which contains a single method: void ejbTimeout(Timer). Also, the security identity during the timer call can be specified using <run-as>; othrwise, permissions cannot be verified.

Lastly, it is not clear how the EJB container provider will know which bean is linked to which timer. Timer creation methods do not have parameters to specify which bean would consume the ejbTimeout events. Plus it would be nice to have the choice of setting up timers declaratively in ejb-jar.xml (this would take effect at deployment time).

Other New Features

Here's a list of (smaller) new features:

Contribute!

You would like to see a feature in the next EJB specification? You think you saw a flaw, a typo, or any kind of mistake? You can influence the future of EJBs. Visit www.jcp.org (Java Community Process) and register as an Expert for free. You will then be able to contribute your ideas.

Emmanuel Proulx is an expert in J2EE and Enterprise JavaBeans, and is a certified WebLogic Server 7.0 engineer. He works in the fields of telecommunications and web development.


Return to ONJava.com.

Copyright © 2009 O'Reilly Media, Inc.