Frank Sommers: What are interceptors, and what role do they play in EJB 3?
Linda DeMichiel: Interceptors give you a convenient way to factor out logic that might be common to multiple components, or that you may not want to have main-line in your code. As an example, you might want to reuse auditing logic, logging logic, or perhaps security logic, in different components.
When a caller invokes a method on the business interface [of an EJB], before delegating that invocation to the component, the container interposes to provide transaction management services—whether to start or check for the existence of a transaction—and the container also interposes for security checks. After this interposition by the container, the interceptor is run.
The interceptor gives the application logic—the interceptor code written by the bean developer—a chance to interpose before the business logic is run. That way, for instance, you can audit who is calling what and under what circumstances. Or you might want to check the arguments [passed in to the business method], perhaps transform those arguments in some way, or you might want to check the results being passed back, or maybe do some custom security. That's typically more sophisticated functionality than you might find in straight business logic—logic that is a little more towards the system edge of the spectrum. So [interceptors] give the developer that interpositioning capability.
You can also insert lifecycle callback methods with interceptors, for example, if you wish to perform some action on activation or passivation. In those cases, interceptors let you move that functionality out of mainline code.
Interceptors' functionality is quite flexible in general. You can have default interceptors, interceptors that apply to all the components in your EJB JAR. You can have a number of default interceptors, and specify in the deployment descriptor the order in which they are run. You can also have interceptors that apply to specific component classes, and define one or more interceptors that run for all the business methods of a class, again specifying ordering. And you can define method-level interceptors that only run for a specific method, or multiple specific methods. And you can customize the ordering in which these interceptors run as well. You even have the capability to exclude default interceptors for a particular class.
Interceptors are configurable by both annotations or XML, with the exception of default interceptors—those can only be configured by a deployment descriptor, since there is no application-level metadata annotation for them.
Frank Sommers: Could you tell us about new features related to dependency injection?
Linda DeMichiel: We debated a number of techniques that we could potentially use [for dependency injection]. The goal was to simplify environment access, and to get away from the requirement of having to use the JNDI API. These were somewhat awkward to use—you had to catch the checked
NamingException, for instance—and were an obstacle to newcomers learning EJB. We were looking for more flexible mechanisms.
Dependency injection, obviously, was not new to EJB. It was out in the community, [and] it served our needs, so it was one of the mechanisms we discussed in our early draft. And it seemed to get considerable traction: the whole [Java EE 5] platform as well seized upon its use.
In EJB 3, a developer annotates either an instance variable or a setter method with the corresponding annotation. When the instance is created, and before the bean comes online to service a method request, the container supplies the annotated component with the reference to the requested resource. Such dependency specification could be done in XML as well, but annotation is considerably more convenient.
The other mechanism is that of a simplified lookup method we added to the
EJBContext interface. That allows you to express the dependency in either annotation or XML, and then call the lookup method to do a dynamic lookup at runtime rather than use injection. The lookup looks up the resource in the JNDI name space.
Both the injection and the lookup are wrappers around JDNI lookup. They're just a simplifying mechanism.
Frank Sommers: A few years ago, you co-authored an open letter to the Java community, calling for a common Java persistence mechanism. One of the main issues was to define a single persistence API for Java. Do you feel that you've achieved that goal with the Java Persistence API? And do you still feel that a common Java persistence API is a good idea?
Linda DeMichiel: Yes, to both questions. The Java Persistence API can be applied more generally [than just for EJB 3], but its target is of course O/R mapping. It can potentially be used more generally, but to do that systematically would require careful consideration and more work.
Frank Sommers: Can you envision this part of the EJB spec split into a separate JSR?
Linda DeMichiel: We had announced the intent that in future releases, we would expect the Java Persistence API to be done in a separate JSR that would be decoupled from the EJB JSR.
Frank Sommers: The common persistence API notwithstanding, there are other projects, such as Hibernate or JDO, that aim to solve a similar problem of O/R mapping, and have thriving followers and communities. When do you recommend a developer use the Java Persistence API, and when would you recommend the use of Hibernate or JDO? Or is that choice just a matter of personal preference?
Linda DeMichiel: We're trying to draw developers onto this model [of the Java Persistence API]. Some of the leading architects of those earlier persistence APIs have been in the EJB 3 expert group now for several years. We have drawn upon their experience, and the experience of the developer communities with these other APIs.
To take the Hibernate example, Gavin King has been a member of this expert group for more than the past two years. We certainly had some influence from Hibernate. And we had influence from JDO, and we had influence from TopLink, as well as influence from the EJB container developers.
All of these leading persistence providers are developing, or have developed, implementations for the Java Persistence API. I think the community is recognizing this, as I had hoped it would, and the Java Persistence API is drawing developers from those communities into it.
In fairness to the Java Persistence API and the work we've done, however, this is essentially a 1.0 release. It doesn't yet have every feature we would want it to have. As it matures, you'll be seeing new functionality added to it, some of which is effectively promised in the existing specification document. We will be broadening the API, but we think we have a very solid core on which to build.
Frank Sommers: What additional features do you envision for the Persistence API?
Linda DeMichiel: We get different requests from different communities. Where a person comes from tends to reflect upon the feature requests we get. There are a lot of features of the API itself that are currently designed to accommodate these different communities.
One of the feature requests we received was [for] mapping types for collections of embedded objects and collections of strings. Some in the expert group didn't� think it was so important, but people who had this [feature] in the API they were using thought it was.
We've gotten requests that the List mapping type support not just an ordering, but that the order manifest as a persistent ordering in the database as well. That request came more from JDO community members who had a different orientation than someone who, say, came from a purely relational database background. From a relational database point of view, a DBA might not recommend that feature.
As another example, JDO uses a persistence-by-reachability architecture: persistence cascades, as it were, to related objects. In the Java Persistence specifications, we offer a cascade option so that you can specify on a per-relationship basis the operations you wish to have cascaded. So [this feature] is selective. To accommodate developers who prefer persistence by reachability as the dominant mode of their application, we provide in the XML [mapping] an option to configure cascade-persist across all relationships.
The use of field-based access type or property-based access type is another example of different developers having different perspectives. Hibernate encourages property access and I think the JDO community would encourage field-based access. We offer both right now: You choose one or the other on the basis of the entity hierarchy. In a future release, I expect we would specify access type at a much finer grain.
The actual feature enhancements that we've been seeing have that flavor. You see different developers with different philosophical or historical backgrounds coming to this API. I think that's healthy because it gives us a variety of perspectives and tells us how people are going to use this API. We try to offer a variety of options which will get more flexible as we move forward, because you can't do everything in a first release.
Frank Sommers: What features did you want to include in EJB 3, but had to leave out from this version?
Linda DeMichiel: In every JSR I've done, you always wind up in a situation [where] there is one more feature, or one more piece of functionality, you really wish you could have. Since EJB 3 is part of Java EE 5, it had to go out with the Java EE 5 [specification], and at some point you really have to draw the line on the release.
One of the things we discussed was better support for asynchronous invocations. Now we have an asynchronous capability with message-driven beans, but I would expect that developers would want to see more flexibility there. We could also use better support around initialization capabilities: when an application comes online, there are often initialization steps that developers would want to see as part of the startup of that application. We have some of these features on the table for possible investigation.
Frank Sommers: Several enterprise Web frameworks emerged in recent years. Their popularity is due in part to such frameworks trying to solve a developer's problem in a more specific way by assuming a lot more within a particular application domain. Do you see EJB, or Java EE, at some point providing that higher-level abstraction?
Linda DeMichiel: One of our goals with EJB 3 has been to provide significant defaulting behavior for expected cases. We tried to take what I loosely term as a "configuration by exception" approach: expected default behaviors are provided for you as a convenience. You don't need to configure them either through annotation or XML.
In terms of frameworks, I am particularly interested in looking at the work being done in the context of Seam, and how that can be used to develop web tier applications by providing a glue between JSF and EJB applications in a very natural and convenient way.
We are interested in learning from non-Java frameworks, as well. When you look at some of the use-cases those frameworks address, I think you'll see that many of them are a lot simpler than the scope of what you can get done with Java EE. But we're looking at them to learn from their good points.
If you'd like to receive a weekly newsletter announcing new articles at Artima.com, please subscribe to the Artima Newsletter.
The EJB 3.0 specifications, including the simplified document mentioned in this article, are available at the following URL:
Have an opinion? Readers have already posted 1 comment about this article. Why not add yours?
Frank Sommers is an Artima senior editor.
Artima provides consulting and training services to help you make the most of Scala, reactive and functional programming, enterprise systems, big data, and testing.