ecently, a friend called to tell me about a huge turnout at an Atlanta JUG meeting to hear about a new product from JBoss called Seam. I went to my keyboard and after just 20 minutes of reading about Seam, I was very impressed. For starters, Seam is based on the lightweight standards in Java EE 5 (J2EE 3) like the new entity bean spec, JSF, annotations, interceptors, and session beans. Like Spring, Seam uses inversion of control but unlike Spring, Seam allows injection of stateful objects. Much of the data movement and framework/API manipulation work that enterprise Java developers have drudged through for 7 years disappears with Seam.
Use cases and user stories record requirements in a conversational manner but Seam is the first product I've seen that facilitates coding in a conversational manner. For the first time, page-level and BPM-level interaction can be a first-class entity in my application. Use cases and user stories actually become the models for code.
On a personal level, I was most impressed when I realized how much code my development team could have saved over the last 3.5 yearsperhaps as much as 40 to 60 percent of our code would be unnecessary using Seam.
Later, my own hands-on experimentation with Seam proved that its promises of less coding and easier development are quite true, which I hope to demonstrate in this article.
| Editor's Note: Mark Smith is a Director at Valtech Technologies, which has a consulting partnership with JBoss, makers of Seam.
Seam has a lot going for it, but to my mind these are the key:
- based on Java EE 5 standards
- a declarative state model
- subversion of control (also called bijection)
Seam builds upon the concepts that the drove the Java EE 5 speclightweight development and ease of use for programmers. Seam has a powerful integration framework for JSF and EJBs. The product eliminates the glue code usually written to integrate these products. The developer is not spending time moving data out of objects and into forms or JSPs but is focusing on delivering business value.
The cost savings Seam provides at the integration level is found mostly in the Hibernate/EJB 3 entity bean approach that Seam is founded on (see Table 1). It removes the logic required to move data from a JDBC call into an object and back into JDBC. It provides complex relationship management at a class level and hides the details of foreign keys and the code required to manage these issues in past JDBC applications. While Hibernate introduced these concepts, with the 3.0 version of the EJB specification, they've been adopted as Java standards. (See "Simplify Java Object Persistence with Hibernate" for more on this model.)
Table 1. Comparative Line Counts with JDBC Calls vs. an EJB 3/Hibernate Approach.
|Class for Customer Integration with JDBC
|Class for Customer Integration with Hibernate
|CustomerFinder.java(just the query method, none of the front end controlling logic)
Seam's declarative state model (see Figure 1) allows you to declare the context with which to manage an object with state. The context can be application, session, conversation, page, event, BPM, etc. By declaring the context of the state, Seam will keep the state around when it is needed and clean it up when you are done. State management eliminates a host of bug and performance problems associated with second-level database caches, stateful session beans, or http session. It also removes the need for the glue code associated with using APIs.
|Figure 1. Inspecting Seam: Seam removes the need for much of the glue code between JSF and the rest of the Java EE 5 specification. It introduces Context management of state into a complex Java EE 5 Web application. SOURCE: JBOSS.|
Inversion of control (IOC), a concept made popular by Spring, is often expressed in a Hollywood term: "Don't call me, I'll call you." The IOC concept moves certain types of work out of application code and into frameworks or containers, moving management of certain APIs away from your code and into a container. Dependency injection, a form of IOC, moves creation or management of identified objects to the IOC container. Whereas you once had to write code to handle the fetching of objects and APIs, dependency injection figures out what objects you're about to use, creates them or gets them, and provides them to the application code. In this way, the objects in your application code have no dependencies on the APIs that create them.
The beauty of the IOC and dependency injection concepts is manifest in Seam with subversion of control and bijection. The difference between IOC and SOC is the ability to "out-ject" as well as inject objects. An IOC container creates or reuses a single instance and injects that into the object needing the resource. Out-jecting allows me to put an object containing interesting state into the container for it to use for injecting later. While IOC only put resources into objects, Seam allows the transfer to go both ways.
Seam uses the following annotations to accomplish injection:
- @Name and @Role identify classes that can be injected.
- @In injects objects.
- @Out (which has no equivalent in Spring) exposes the changes made in the injected object to other objects that may need to see them.
- @Scope puts the Seam Component (identified with @Name) into the declarative state management framework.
- @Scope(CONVERSATION) puts a Seam Component into the state management framework at the conversational level.
Seam makes extensive use of annotations, including both EJB 3.0 annotations as well as its own. Putting database mappings and other API configuration information in annotations reduces the complexity of using third-party frameworks and improves one's ability to read and understand code because it is no longer in a separate XML file.
SOC combined with the declarative state model is a powerful combination. It is how you begin to code in a conversational manner. This facilitates complex page flow, particularly when using JBoss' jPDL product, for which Seam provides native integration (see Figure 2). JBoss' jBPM fits into the programming model with ease, where in the past it BPM types of tools never seemed to mesh well with the old programming models.
|Figure 2. Managing Workflow: Seam has the ability to manage page flow graphically through jPDL. jPDL is also used to manage workflow in jBPM.|
Managing Page Flow with Seam
There are two ways to manage page flow with Seam. The first is very basic: When a button is pushed, it is passed a string that is then mapped to the next page. The routine that returns the string is where the complex page flow logic resides. In this example, I use the basic XML file, also called the stateless navigation model:
The other Seam page flow model, called jPDL, is an XML file that defines a process definition language. jPDL has a very nice graphical interface, which is a powerful tool when dealing with complex page flows.