作者: Reza Rahman 文章来源: www.theserverside.com
In the first article, I urged you to provide feedback directly to the JCP at jsr-318-comments@jcp.org as well as CCing me at rrahman@tripodtech.net. Before going farther, I would like to thank everyone who took the time to send in comments! I hope you will continue to send in your thoughts as I write more articles in this series. I am also very grateful for all of the encouraging comments on the series itself.
It's Time for Timer Service Features
Scheduling is an important part of many applications for tasks such as report generation, database maintenance, generating OLAP summaries or data synchronization. If you have used the EJB Timer Service in its current form, you know that it is useful, but pretty limited. The biggest limitations of the current EJB Timer Service are that it is not all that flexible and scheduled jobs can only be created programmatically, not declaratively. Some of these weaknesses were outlined by Richard Monson-Haefel in the EJB 2.x time-frame. This TheServerSide article outlines Richard's views: http://www.theserverside.com/tt/articles/article.tss?l=MonsonHaefel-Column4.
Let's take a super-quick look at the Timer Service as supported in EJB 3.0. Here is an example from EJB 3 in Action:
The Stateless Session bean above creates a timer that is triggered every fifteen minutes, starting with a fifteen minute delay when a bid is created in the addBid method. Every time the trigger fires, the monitorBid method annotated with the @Timeout annotation is invoked to see if the bidder was outbid.
While this functionality is fine for what PlaceBidBean does, imagine a slightly different scenario–a beginning-of-the-month newsletter mailing for all ActionBazaar customers. Implementing this in terms of millisecond intervals through the current programmatic TimerService interface would be a hazard at best. You'll also have to write some pretty awkward code so that the timer is created when the application starts up. There are several existing mechanisms in place today to achieve this kind of flexible declarative schedules in Java EE. You can use a popular Open Source scheduler like Quartz, you can use a commercial tool like Flux or you can use scheduling services specific to your application server such as the ones available for WebLogic or Sybase EAServer. The problem with these solutions is that they tend to be pretty cumbersome if all you really need is a declarative equivalent of UNIX cron in Java EE. All these solutions are also vendor-specific. Enter the Timer Service enhancements in EJB 3.1.
The most important one in this set of enhancements is the ability to declaratively create cron-like schedules to trigger EJB methods (there are more advanced features; feel free to check them out when the spec draft comes out). For example, all you would have to do is annotate an EJB method with the @Schedule annotation to implement the beginning-of-the-month ActionBazaar newsletter like so:
The following table describes the attributes of the @Schedule annotation as well as default values:
Attribute |
Allowable Values |
Default |
Second |
[0,59] |
0 |
Minute |
[0,59] |
0 |
Hour |
[0,23] |
0 |
dayOfMonth |
[1,31] |
* |
Month |
[1,12] or {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", Dec"} |
* |
dayOfWeek |
[0,7] or {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"} |
* |
Year |
A four-digit calendar year |
* |
Note any of the attributes support the cron-style "*" wildcard to represent all values, a comma separated list (such as "Jan, Feb, Mar" for the month attribute) or a dash-separated range (such as "Mon-Fri" for the day of week attribute). Should the expression syntax support the "/" operator as well? How about supporting fully expanded abbreviations such as "January" instead of "Jan"? Also, should a compact, full cron-expression format be supported as well? Our little example could be expressed as:
Some folks argue that this "pure cron style expression" is way too cryptic, while others point out that a lot of developers are so used to it that it should be supported in EJB. New methods were added to the TimerService interface to support the programmatic version of cron-like scheduling. The programmatic version supports defining the activation and deactivation dates for a given schedule. For example, our newsletter could become active at a predetermined time in the future instead of being active as soon as the timer is created. Should similar support be added to the @Schedule annotation? How about supporting defining a finite number of occurrences a cron-based trigger will fire? Can you think of any other features?
Stripped Down EJB Packaging
Making XML deployment descriptors optional in EJB 3.0 has significantly simplified packaging and deployment of Java EE applications. However, Java EE packaging is still clearly oriented towards strict modularization. Namely, you must create separate jar files for web and EJB modules. In a typical Java EE deployment scenario, an EAR file will contain a war archive and a separate EJB jar. Figure 1 depicts the current Java EE packaging scheme. Roughly, the idea is that the EJB jar represents "modularized" business services that are consumed by the "client" web module. While modularization is very important, the problem is that it is overkill for simple web applications where business services are unlikely to be shared across clients in multiple other Java EE modules.
Figure 1: Current Java EE packaging.
Simplified EJB packaging for web applications is aimed at addressing this issue. In the new scheme, there is no need to create a separate EJB jar module. Rather, EJBs (especially in the form of annotated POJOs) can be directly dropped into the WEB-INF/classes directory and deployed as part of the WAR. In a similar vein, the ejb-jar.xml deployment descriptor, if you happen to be using one, can be placed into the WEB-INF directory along with the web.xml file. It may also be possible to place an EJB jar into the WEB-INF/lib directory (do you think this is important?). The new packaging scheme is depicted in Figure 2.
Figure 2: Simplified EJB packaging for web applications.
For me, a very interesting implication of this is that the simplified packaging scheme makes EJBs much more agnostic of the rigidly defined structure of Java EE EAR files. There is another really nice side-effect for those of us that still live in the land of occasional XML configuration and JNDI look-ups instead of 100% annotations and DI. All EJB references, resource references or environment entries defined anywhere in the WAR can now be shared. This is because the entire WAR file has only one local component environment (bound to the JNDI java:comp/env namespace). Let's say you define a data source reference in the web.xml file like so:
You can now do a lookup like the following not only in web container components like Servlets but also inside EJBs packaged inside the WAR:
What are your thoughts on this? There is one more reason I really like the simplified packaging enhancement—it goes hand-in-hand with EJB Lite. EJB Lite is a very minimal sub-set of EJB features designed for use in stripped-down applications. I'll talk more about EJB Lite in a later article in the series. One interesting possibility is that many vendors will likely start implementing EJB Lite on top of Servlet containers like Tomcat or Jetty, with EJBs directly deployable to WAR files, completely by-passing Java EE EARs. I see JBoss AS Express, GlassFish Express or Tomcat+OpenEJB as possibilities that are difficult to ignore, especially given Java EE 6 Profiles. What do you think of these possibilities?
More to Come
Believe it or not, the features discussed in the first and second parts of this series are still just the tip of the iceberg. Here are some of the more interesting ones I'll cover in this series:
- EJB support in minimal containers in the form of EJB Lite. This would be similar to what is already available in the Open Source world in the form of Embedded JBoss, OpenEJB and EasyBeans plugging in on top of Tomcat.
- Support for asynchronous Session Bean invocation.
- Support for stateful web services via Stateful Session Bean web service endpoints.
- The standardization of JNDI mapping instead of keeping it for vendors to decide is being preliminarily discussed.
Something else I am intending to discuss in the series is using EJB through Web Beans. As you might already know, Web Beans is a very powerful integration framework that makes it possible to use some very interesting DI features with EJB, an area Java EE has been criticized by a number of folks. The Web Beans specification is being led by Gavin King and incorporates ideas from JBoss Seam and Google Guice ("Crazy" Bob Lee of Guice fame is working on WebBeans too). Until then, wish the expert group luck and keep the feedback rolling!
References
- JSR 318: Enterprise JavaBeans 3.1, http://jcp.org/en/jsr/detail?id=318.
- JSR 299: Web Beans, http://jcp.org/en/jsr/detail?id=299.
As per Linux conventions, either 0 or 7 can be used to represent Sunday.