After stumbling out of the gate, Entity Java Beans return with a whole new attitude.
In my most recent article on Service-Oriented Architecture (SOA), I mentioned that I consider Simple Object Access Protocol (SOAP) to be terribly over-engineered. In that same article, I mentioned my longstanding opinion that Enterprise JavaBeans (EJB) was originally in the same category. I in fact once said EJB was one of the first technologies that had "jumped the shark" before being officially released.
However, EJB has evolved. Unlike Happy Days, which gently fizzled out after spawning Joanie Loves Chachi (both stars of which ended up in reality TV, but I digress), the EJB community continues to try to get it right, and the latest incarnation, EJB3, seems to have gotten much closer.
The problem when technologies such as this go through updates, though, is that sometimes the user community doesn't follow along, and you end up with orphans. For example, there are still a lot of Struts shops out there, even though Struts is clearly on its last legs as a technology. And while Struts may be the largest example, plenty of others have come and gone, particularly in the Java space.
IBM Buy-In Helps
And that's why WebSphere's inclusion of EJB3 support (as an add-on feature pack to the 6.1 version) is important. Love it or hate it, WebSphere is one of the vanguards of the Java EE movement. And while some fault WebSphere for not always moving as quickly as other application servers when incorporating new technologies, when a feature shows up in WebSphere, it can be said to have matured.
Certainly, the community has been looking for WebSphere to adopt EJB3, and the availability of the feature pack very late last year definitely gave some extra impetus to adopt this newest technology. The recent adoption of EIM support throughout the WebSphere line has certainly given a boost to the Single Sign-On (SSO) strategy. The Apache HTTP server on the i will now negotiate credentials with Internet Explorer, meaning that a user can log onto Windows and then use WebSphere applications through the browser without having to sign on again. Until this technology was enabled, the idea of SSO was somewhat limited because you could use it for desktop applications but not for browser-based systems.
And although EJB3 is more of a programming technology than an administrative one, I think WebSphere support for EJB3 will similarly help with its uptake.
What Is EJB3?
EJB3 is a marked step away from traditional EJB. Whereas EJB up to Version 2 was a very heavy protocol requiring definition of multiple classes and lots of XML configuration, EJB3 uses a completely different approach that relies heavily on annotations and dependency injection.
If you're not a Java guru, this might not mean much. But in the long run, it has several major functional ramifications:
- Beans are Plain Old Java Objects (POJOs).
- Persistence is maintained using an Entity Manager.
(Hibernate users will appreciate this.) - Code is injected at runtime.
The tradeoff is pretty major: You no longer need to create big XML files to define your Beans; instead, your code is going to be altered at runtime. The latter point becomes very important when you're talking about deployment and especially debugging.
Beans Are POJOs
It's hard to over-emphasize just how important this is. Prior to EBJ3, all Entity Beans had to implement the rather cumbersome EntityBean interface, which in turn required implementing a range of methods designed to support the persistence process. Even if you didn't use these methods (and most Beans didn't), the developer had to create all of them, which meant a whole lot of unused and useless methods. The developer had to create support classes, such as the Local and LocalHome classes, and then had to describe pretty much the entire database definition of the class in XML in the deployment descriptor. This included everything from the individual fields in the table to the class that defines the primary key to the methods that are used to find instances of the entity. Add to that the definitions of relationships between tables, and as you might imagine, the definition of large databases became quite involved and generated huge files.
With EJB3, all of this goes away. You simply define your Bean as an everyday POJO and then you add annotations as needed to describe the database natures of the object. It's an example of the complexity of the previous approaches that Java developers even needed the term POJO, but the truth is that class definitions especially for EJBs were spiraling out of control. With EJB3, you return to the simplicity of defining an object whose fields represent the actual attributes of the object. You add the annotations to then describe the Object-Relational Mapping (ORM) characteristics.
@Column(name="DBANAME")
public String getDoingBusinessAs(){
return doingBusinessAs;
}
This simple example shows how the attribute name in the class is not necessarily the same as the column name in the table (and in fact, depending on your database schema design, these may nearly always be different). Here's another example:
@Column(name="ORDER_COST", updatable=false,
precision=12, scale=2)
public BigDecimal getCost() { return cost; }
I took this right from the Java EE 5 documentation, but look at what you see: updatable=false tells you that this value is not directly modifiable by the application (in this case, it's the total order cost, which is calculated based on other values in the database). Notice also that the annotation provides additional definition elements such as scale and precision, which are beyond the simple object type of BigDecimal. These elements are used during the ORM phase to help move data between the database field and the corresponding Java object.
EJB3 supports the EJB Query Language (EJB-QL) to define the syntax of queries and has made it very easy to define not only primary queries but also additional queries to support other access techniques. One of the things I've always found frustrating with some types of code generation facilities is the fact that database access is limited to the primary key, when in the real world we need to access rows in a table in a variety of ways.
Also, EJB3 has support for inheritance, and it seems to be done intelligently. When you use a database to create types and subtypes, you do it in two distinct ways: One is to have a single table and then use a flag to determine the type; the other is to have common data in one table and then create additional tables to hold specific information for each subtype. EJB3 has direct support for both. That's one of the really nifty things about the annotation syntax; since annotations are keyword/value-based, developers can add a lot of capability without having to change the syntax, so they can focus on this sort of usability. Contrast this with the overwhelming amount of work that went into adding generics to the base language and the resulting complex (some would say overly complex) syntax. Let's hope that the annotation designers and the EJB3 folks in particular continue to stick with the KISS principle.
Entity Managers Provide Persistence
The actual persistence part of the specification is done via something called an Entity Manager. I keep bringing up this term, but it's important. The Entity Manager is to high-level persistence as a JDBC driver is to a database. An Entity Manager is a class that implements a specific interface (javax.persistence.EntityManager), which in turn is part of the Java Persistence API introduced with Java EE 5. This interface has a number of high-level abstractions that have to do with managing beans and was built with a lot of attention being paid to existing frameworks such as Hibernate and TopLink. And in fact, both Hibernate and TopLink have Java Persistence API (JPA)-compatible interfaces so that you can use either one as your persistence engine and thus use any database they use.
It's an interesting double layer of abstraction, but it seems to work well. You define your Beans at the business level, and through annotations, you describe them to the persistence engine. The persistence engine itself is defined in the deployment descriptor, along with whatever information is need to identify the database to be used.
One of the things that I need to spend a little more time on is the concept of security. I know security is at least addressed in the JPA specification, but I don't know exactly how it's implemented. Specifically, I don't know how user credentials are passed from the active session to the database layer. It seems to me that it will be very important as part of the overall concept of EJB3 to be able to pass the user ID that was initially used to authenticate the session down to the database layer and use that to authorize data-level transactions. It's one thing to have a single user ID and password that you use for standard database requests (such as you might have for a storefront catalog), but it's another thing entirely to ensure both row- and column-level security based on the user ID.
Further along those lines, with the increasing use of SSO technology, it would make sense that the identity token, whether it be Kerberos or EIM, would also need to be supported.
Annotations? Dependency Injection?
Yeah, this is a little scary. The concept of annotations is complex, and while it provides powerful capabilities to the Java language, it removes it one step from the world of nuts-and-bolts programming. In essence, an annotation is a syntax element that doesn't actually generate code; it is more of a comment that affects how the compiler works--or even more scary, how the code is processed at runtime.
The compiler-level annotations are pretty simple; they allow you to log messages or even create additional source files for later compilation, but they don't actually affect the code. Runtime annotations, on the other hand, can be used by other parts of the system to affect how your code works.
In the simplest scenario, let's take the concept of the Entity Manager. With an interface like this, prior to the concept of annotations you would get the Entity Manager from a factory of some kind:
EntityManager em = createEM("aParm", "anotherParm");
The parameters could come from a configuration file or could be determined based on user ID or application or any number of things. The perceived problem with this approach was that you might have to change that line of code whenever you wanted to add a new implementation of EntityManager, and that would not be configurable. The new technique the designers came up with was the annotation. It works like this:
@PersistenceContext
EntityManager em;
Yes, I know what you're thinking. What's that odd "at" sign (@), and how is this going to create an Entity Manager? Well, in the world of annotations, one of the things that can happen is that code can be inserted at runtime to do things. In this case, the annotation is @PersistenceContext, and it will insert ("inject") an EntityManager instance (a "dependency") into the field em when it is needed. I'm a little bit hazy as to when this occurs. Is it when the class is first loaded, or is it whenever the class is instantiated, or does it perhaps depend, for example, on whether the variable is a static, dynamic, or temporary variable?
This can be a little unsettling at first. There is no code to debug; you just have to rely on the dependency injection to work. And that in turn depends on the "container," the environment that the application runs in. This is something above and beyond the Java Virtual Machine (JVM); this is a set of JAR files that control how the application executes, forming yet another virtual layer upon which the application runs. In the Web world, it's pretty easy: You add this sort of support code in your servlet container. However, once you step away from the Web environment, it becomes a little trickier, especially for standalone Java applications. Somehow, you have to create the same sort of container that surrounds servlets, and that's not always intuitive.
Issues also exist for IDEs such as Eclipse or Rational; not only do they have to support the basic annotation syntax (which is part of Java 5), but they also have to understand what the annotations do. For instance, in the second example above, if you tried to use the variable em, you would normally get an error in the editor telling you a field was not initialized. The editor would have to not only accept the @PersistenceContext annotation as valid syntax, but also realize that it will initialize the em variable so that later references are not flagged as errors. This seems to me to be no small feat!
Despite my ignorance, however, the stuff works. So I suppose I should just bag my pessimism and move on, because the benefits of this approach are quite substantial.
So Does EJB3 Finally Make EJB Usable?
Yes, I think so--at least, as soon as all the pieces are in place. My biggest problem right now is making sure that the tools will directly support the code injection. Currently, the JavaServer Faces (JSF) tooling in Eclipse and Rational won't support the EJB3 annotations. This means that if you had to do some tricky bits of Java within your JSF, you'd have to manually mimic what the annotations do.
Another stumbling block is non-Web applications. While the authors of EJB3 seem to have some idea of how you can get around this by using an Application Client Container, the concept that your application has to run inside a container at all may be off-putting to some developers. However, like JSF coding, the non-Web applications seem to have some ability to get around the issue temporarily by using manual code to manage the interface to the Entity Manager. I'm just not sure how much needs to be added to a standalone Java application in order for it to take advantage of the EJB3 capabilities.
Which brings us back around full circle to WebSphere. Because WebSphere does have full support for EJB3, I think people will be interested in trying it out. The quicker Rational builds all the needed support into its supplemental tooling, the more rapid the uptake of the technology.
And once that happens and it's proven that the EJB3 concept works well in Web applications, I think you'll see both the use of EJB3 for non-Web applications as well as an acceptance of the application-container technique. And finally, at that point, we may just see the ability to start to create good business applications using Java, since EJB3 will have removed much of the plumbing from the database side of the application.
LATEST COMMENTS
MC Press Online