Friday Apr 03, 2009

Many developers have asked about the relationship between JAX-RS (Java API for Restful Web Services) and Enterprise JavaBeans. The good news is that in Java EE 6, session beans can be implemented as JAX-RS resource or provider classes. The two work very well together thanks to JAX-RS flexibility in handling many kinds of resource classes, the EJB 3.1 no-interface view, and the ability to package enterprise beans directly in a .war.

One simple class functions as both a full-fledged JAX-RS resource and a stateless or singleton session bean. It can take advantage of all JAX-RS and EJB 3.1 functionality, including injection of JAX-RS context information, container-managed transactions, simple access to other managed EE resources such as JPA persistence contexts, etc.

See Paul Sandoz's blog for more details and a pointer to an early access implementation.

Wednesday Mar 11, 2009

I'm pleased to announce that the EJB 3.1 Proposed Final Draft is now available. We're well on our way towards finalizing what I'm sure will be a vastly improved version of Enterprise JavaBeans. The spec includes many clarifications to the requirements from the previous drafts, as well as some small feature improvements. Here are a few of the notable changes :

Improved portable Local Session Bean lookups

The EJB 3.1 Public Draft introduced portable global JNDI names for session beans. While the global syntax works great for Remote lookups, it is not ideal for dynamic lookups of Local session beans. We've gotten a lot of feedback that it's too cumbersome to have to declare an ejb-local-ref or @EJB annotation just to retrieve a session bean defined within the same module.

The problem with the portable global JNDI name syntax is that it requires knowing the module name and potentially the application name in order to make the lookup. To minimize these dependencies, we're adding JNDI syntaxes based on two new portable naming scopes called java:module and java:app.

java:module lookups are scoped to the module in which the lookup occurs. They allow session beans to be retrieved based only on the ejb-name.

java:app lookups are scoped to the application in which the lookup occurs. They allow session beans to be retrieved based only on the module name and the ejb-name.

For example, given the following Stateless session bean :

   1:  @Stateless 
   2:  public class HelloBean {
   3:     public String hello() { return "hello, world\n"; }
   4:  }

Any code running within the same module as HelloBean can portably retrieve its reference as follows :

   1:  InitialContext ic = new InitialContext();
   2:  HelloBean hb = (HelloBean) ic.lookup("java:module/HelloBean");

Likewise, if HelloBean is packaged in hello.jar, any code running in a module within the same .ear can portably retrieve its reference using the string "java:app/hello/HelloBean".

See Section 4.4 for more details.

Timezone support for calendar-based timers

One of the limitations of calendar-based timers as defined in the Public Draft is that their schedules can only be specified relative to the time zone in which the application is deployed. That means if you want a calendar-based timeout to occur at a specific time in a given time zone, there's no easy way to do it.

The Proposed Final Draft addresses this by allowing an optional time zone ID to be associated with a calendar-based timer. In that case, all timeouts occur relative to the specified time zone. Time zones are supported no matter how the calendar-based timer is defined : programmatically, via annotation, or in ejb-jar.xml.

For example, the following code defines an automatic calendar-based timeout that occurs at 10 a.m. U.S. Eastern Time every day, independent of where the application itself is running :

   1:  @Schedule(hour="10", timezone="America/New_York")
   2:  public void timeout() { ... } 

See Section 18.2 for more details.

Spec-defined stateful session bean timeouts

Developers are always asking why there isn't a spec-defined way to specify the stateful session bean timeout value. Stateful session beans have always had the notion of a timeout, yet it has been left to the vendors to define the configuration for this value. The Proposed Final Draft defines a portable way to specify it.

   1:  @Stateful
   2:  @StatefulTimeout(value=10, unit=TimeUnit.MINUTES)
   3:  public class CartBean { ... }

@StatefulTimeout specifies the amount of time a stateful session bean can be idle (not receive any client invocations) before being eligible for removal by the container. The time unit is optional and defaults to MINUTES. Like all of our annotations, the stateful timeout metadata can also be specified in ejb-jar.xml.

See Section 4.3.12 for more details.


Please check out the spec and leave feedback here or at jsr-318-comments@jcp.org. Note that given where we are in the process the top priority is fixing spec bugs and problems with the APIs. Of course, we're always interested in hearing feature requests for future EJB versions :-)

Friday Nov 07, 2008

Now that the GlassFish v3 Prelude release is available it's a great time to try out some EJB 3.1 features that are being developed as part of the reference implementation. We have an EJB 3.1 module that provides early access implementations of the following functionality :

See Mahesh's blog for details on downloading the module through the Update Center and running a sample application.

Monday Oct 06, 2008

Dealing with session bean global JNDI names is a common source of frustration for EJB component developers. Global JNDI names have always been outside the scope of the specs. Even though most Java EE implementations take the same high-level approach to their use, the actual syntax is typically different for each product. This leads to developer confusion and requires additional configuration steps for each deployment environment. Portability issues are also common as developers mistakenly embed the vendor-specific global JNDI names in the source code.

We're planning to solve these problems by defining portable global JNDI names for session beans.

Let's take a look at a simple example. Here's a basic stateless session bean exposing a remote business interface :

   1:  @Stateless
   2:  public class FooBean implements FooRemote { ... }

The two most common client scenarios are :

a) Remote EJB dependency from a Java EE component in a different application

   1:  @EJB 
   2:  FooRemote foo;

Since the target bean resides outside the application, there is no standard way to tell the deployment environment how to resolve the @EJB dependency.

b) Remote access from a "stand-alone" (non Java EE) component

   1:  FooRemote foo = (FooRemote) 
   2:    new InitialContext().lookup("<global_jndi_name>");

In this case there is no standard string to use in the context lookup.

Our proposed solution is to define a standard global namespace that has a well-defined name for each session bean. For example, if FooBean were deployed as fooejb.jar, its standard global JNDI name would be "java:global/fooejb/FooBean".

The revised, now portable, client examples become :

a) Remote EJB dependency from a Java EE component in a different application

   1:  @EJB(mappedName="java:global/fooejb/FooBean")  
   2:  FooRemote foo;

Note that the existence of portable global JNDI names does not mean that the Java EE component environment should be bypassed. There are still many advantages to using @EJB or ejb-ref as a way to declare the caller's dependency on an enterprise bean. An important one is the option to move the global JNDI name mapping information to a descriptor so that it's not hard-coded.

b) Remote access from a "stand-alone" (non Java EE) component

   1:  FooRemote foo = (FooRemote) 
   2:    new InitialContext().lookup("java:global/fooejb/FooBean");

Non Java EE clients do not have access to a component environment so they must perform an explicit global lookup. The spec-defined global name at least ensures that the lookup string will be uniform across Java EE products.

The previous examples deals with the remote view, but the portable global JNDI names apply to session beans exposing Local and no-interface views as well. This is especially useful in conjunction with the new EJB 3.1 embeddable API.

More generally, the syntax for determining a session bean's portable global JNDI name is :

 java:global[/<app-name>]/<module-name>/<bean-name>

Application name and module name both default to the unqualified name of their respective bundle, minus the file extension. Each name will also be configurable via a standard deployment descriptor element. Application name only applies when the application is deployed in a .ear file. Bean name defaults to the unqualified name of the bean class, unless set as the name() attribute on the component-defining annotation or in the ejb-name element of ejb-jar.xml.

The spec will also define a variation of the global name syntax for identifying a particular client view of a session bean. This is useful for the case that a single session bean exposes multiple client views. The only difference is an additional field for the fully-qualified interface name (or bean-class type in the case of the no-interface view) :

 java:global[/<app-name>]/<module-name>/<bean-name>/<intf-name>

Wednesday Oct 01, 2008

Now that the EJB 3.1 Public Draft is available, here's a list of its main ease-of-use improvements and features, along with their corresponding sections in the spec. This should make it easier to quickly find some of the most relevant material. While it's true that the spec is a bit, shall we say, on the "large" side, I think you'll find that most of the new content is concentrated in a relatively small number of pages. Happy reviewing :-)

  • The "no interface" Local view (3.4.4 , 4.9.8)
  • Portable global JNDI names (4.4)
  • Asynchronous session bean invocations (4.5)
  • Singleton session beans (4.8)
  • Startup / Shutdown callbacks (4.8.1, 4.8.2)
  • Calendar-based timer expressions (18.2.1)
  • Automatic timer creation (18.2.2)
  • Non-persistent Timers (18.2.3)
  • Deployment of EJB components directly in a .war without an ejb-jar (20.4)
  • EJB "Lite" -- a standard lightweight subset of the EJB API (21.1)
  • Embeddable EJB -- an API for executing EJB components within Java SE (Ch. 22)

I'm happy to announce that the EJB 3.1 Public Draft is now available. (Download it here) The Expert Group has been working hard to improve the spec since we released the Early Draft in February, driven in large part by the community feedback we've received. We encourage you to help us continue that effort by leaving review comments below or by sending email to jsr-318-comments@jcp.org. I'll be following up with a more detailed look at the content so stay tuned...

Tuesday Jul 29, 2008

One of the most common requests we hear from Enterprise JavaBeans developers is for improved unit testing support. The two biggest issues they raise are :

  • Testing Local Session Beans is difficult since they're only accessible by way of the Remote EJB tier or the web tier.
  • Regardless of bean type, it would be simpler to allow client code to run in the same JVM as the components under test.

Some Java EE implementations have solved these problems by adding a Java SE execution mode in which clients instantiate EJB components within the same JVM. While this is a great start, more work is needed to raise the level of portability and ensure broader support.

We've been discussing this topic extensively in the EJB 3.1 Expert Group. Here's an early look at a proposed solution we're calling Embeddable EJB :

The Embeddable EJB API allows client code to instantiate an EJB container that runs within its own JVM and classloader. The client uses a spec-defined bootstrapping API to start the container and identify the set of enterprise bean components for execution.

The embeddable EJB container provides a managed environment with support for the same basic services that exist within a Java EE runtime : injection, access to a component environment, container-managed transactions, container-managed persistence contexts, etc. In general, enterprise bean components are unaware of the kind of managed environment in which they are running. This allows maximum reusability of bean components across a wide range of testing and deployment scenarios without significant rework.

Let's look at an example. Here's a simple Stateless session bean that uses Java Persistence to implement some bank account operations :

   1:  @Stateless
   2:  public class AccountBean {
   3:   
   4:    @PersistenceContext EntityManager em;
   5:   
   6:    public void createAccount(int acctId) {
   7:   
   8:      Account account = new Account(acctId);
   9:   
  10:      em.persist(account);  
  11:   
  12:    }
  13:    ... 
  14:  }

Note that this is just a normal stateless session bean. It exposes business methods through a no-interface view. The bean implementation uses injection, container-managed transactions, and Java Persistence. There is no special API it must use to be capable of embeddable execution.

Here is some test code to execute the bean in an embeddable container :

   1:   
   2:  // Instantiate an embeddable EJB container and search the
   3:  // JVM class path for eligible EJB modules or directories
   4:  EJBContainer ejbC = EJBContainer.createEJBContainer();
   5:   
   6:  // Get a naming context for session bean lookups
   7:  Context ctx = ejbC.getNamingContext();
   8:          
   9:  // Retrieve a reference to the AccountBean using a
  10:  // portable global JNDI name (more on this later!)  
  11:  AccountBean ab = (AccountBean) 
  12:      ctx.lookup("java:global/account/AccountBean");
  13:   
  14:  // Test the account
  15:   
  16:  Account a1 = ab.createAccount(1234);
  17:   
  18:  ...
  19:   
  20:  // Shutdown the embeddable container
  21:  ejbC.close();    
  22:   

Next we prepare the following three .jars :

  • account.jar
    An ejb-jar containing the AccountBean class and its associated persistence artifacts.

  • client.jar
    A .jar containing the test client class.

  • vendor.jar
    A vendor-provided .jar file containing the necessary system classes.

All that's left to do is start the JVM using a normal java command :

% java -cp account.jar:client.jar:vendor.jar com.acme.AccountTest

It's important that we support starting the JVM with a plain java command. Not only is it easily understood by developers but it ensures straightforward integration with existing test frameworks and IDEs. We also plan to support an "exploded" directory form of the ejb-jar to reduce the number of packaging steps.

There are more details to work out but we think this is a good first step. As always, let us know your feedback by leaving comments here or by sending email to jsr-318-comments@jcp.org.

Tuesday May 06, 2008

The Reference Implementation for EJB 3.1 is being developed as part of the Glassfish project. A preview implementation of two new ease-of-use enhancements (simplified packaging and the "no-interface" view) is now available. See Mahesh's blog for the details. Give it a try and let us know your feedback.

Friday Mar 14, 2008

The EJB 3.0 Specification simplified many aspects of EJB component development. It reduced the number of required classes and interfaces, established intelligent defaults, and made the ejb-jar.xml file optional, to name just a few.

However, the specification still requires that all EJB components be packaged within an ejb-jar file. In many cases this restriction adds undue complexity to Java EE development. To remedy that, we're planning to allow EJB components to be packaged directly within a .war file, without the need for an ejb-jar.

Let's look at an example. Assume we have a simple Stateless Session Bean that exposes a no-interface view :

   1:  package com.acme;
   2:   
   3:  @Stateless
   4:  public class FooBean {
   5:    public void foo() { ... }
   6:  }

Normally, accessing this bean from a Servlet would require one .war, one ejb-jar, and an .ear file to wrap the two modules together. With the new packaging alternative, everything fits into a single .war :
$ jar tf foo.war 
WEB-INF/classes/com/acme/FooBean.class
WEB-INF/classes/com/acme/FooServlet.class
WEB-INF/web.xml

It's important to point out that the goal here is to remove an artificial packaging restriction, not to create a new flavor of EJB component that uses web container APIs. From an EJB component's perspective it still lives within the same managed runtime environment as before. This is important, as it keeps the programming model independent of packaging decisions.

Here are some more details about how the new packaging approach would likely be defined :

  • EJB component classes are packaged within WEB-INF/classes and/or in WEB-INF/lib.
  • EJB components share the same classloader as other classes in WEB-INF/classes and WEB-INF/lib.
  • EJB components share the .war's module-level component environment. For example, a resource-ref defined within web.xml would be visible to any EJB components in the .war.
  • EJB components have visibility to any persistence units defined within the .war.
  • ejb-jar.xml is optional. If needed, it is placed in WEB-INF/.
  • There are no special restrictions placed on a .war just because it contains EJB components. It can be deployed as a stand-alone .war or included within an .ear along with any number of other .wars or ejb-jars.
  • The full EJB feature set is available. For example, it would be possible to define a message-driven bean by placing a bean class annotated with @MessageDriven within WEB-INF/classes.

That's a quick overview of a new simplified alternative to EJB component packaging. Please post comments here or send them to our EJB 3.1 feedback alias.

Wednesday Mar 12, 2008

I presented an overview of Enterprise JavaBeans 3.1 (JSR 318) last December at the JavaPolis '07 conference in Antwerp, Belgium. Here are the slides and video.
The EJB 3.0 Simplified API made it much simpler to write a Local business interface for an EJB component. But what if you don't even need a separate interface? That's an issue we're planning to address in the EJB 3.1 Specification by making local business interfaces optional.

Let's start by looking at an example of a simple EJB 3.0 stateless session bean exposing a Local view :

   1:  public interface Hello {
   2:    public String hello();
   3:  }
   4:   
   5:  @Stateless
   6:  public class HelloBean implements Hello {
   7:    public String hello() { return "hello"; }
   8:  }

Here's a client of that bean :

   1:  @EJB Hello helloRef;
   2:  ...
   3:  helloRef.hello();

Pretty straightforward, but in some cases developers find it cumbersome to use a separate interface as the contract for their client. This is especially true for fine-grained components accessed locally from clients within the same module. It's one more file per component to write and keep in sync with the bean class, and one more .class to package into the application.

Here's how a corresponding EJB 3.1 component using a "no-interface view" might look :

   1:  @Stateless
   2:  public class HelloBean {
   3:    public String hello() { return "hello"; }
   4:  }

All public bean class methods are exposed as the client method contract. The client acquires an EJB reference the same way as before. The only difference is that the reference type is a bean class instead of a local business interface :

   1:  @EJB HelloBean helloRef;
   2:  ...
   3:  helloRef.hello();

It's important to note that even though there is no interface, the client still interacts with the bean through an EJB reference object. The client never directly instantiates the bean class using the new() operator or holds a direct reference to a bean instance. This makes the client programming model almost identical between the Local view and the no-interface view. All semantics regarding transaction propagation, exception handling, concurrent access, etc. stay the same.

We think the no-interface view will be one of many nice options for simplifying EJB applications going forward. What do you think? Please post comments here or send them to jsr-318-comments@jcp.org.

Monday Mar 10, 2008

I'm happy to announce that the Enterprise JavaBeansTM (EJB) 3.1 Early Draft is now available.

The Expert Group has been working hard since we launched JSR 318 last August and we're looking forward to your feedback. Please send comments to jsr-318-comments@jcp.org

The EJB 3.1 Specification has two main goals. The first is a continued focus on ease-of-use. The EJB 3.0 Specification made a huge improvement in this area with the introduction of the EJB Simplified API but we can do much more. The second goal is to add many of the new features that have been requested from the community for some time.

Here is a brief overview of the topics being considered. I'll be following up with more detailed posts on each topic. Just a reminder that we're still relatively early in the process so the exact feature set is subject to change.

.war packaging of EJB components
The EJB 3.0 Specification made it simpler to develop EJB components by reducing the number of necessary classes and .xml files. However, EJB components are still required to be packaged within their own ejb-jar file, which complicates the development of applications that make use of both web and EJB functionality. This enhancement will allow EJB components to be packaged and deployed directly within a .war file, without an ejb-jar.

Optional Local Business Interfaces
Although the EJB 3.0 Local view has proven to be a significant improvement over its predecessor, there are cases where developers would prefer to avoid using a separate interface altogether. Making the local business interface optional will allow a bean developer to implement a component using only a bean class.

EJB "Lite"
The Java EE 6 Specification will be introducing Java EE platform Profiles. Profiles will reference the Java EE platform, as defined by the JCP process, and may include a subset of Java EE platform technologies, additional JCP technologies not part of the base Java EE platform, or both. EJB "Lite" defines a small portion of the EJB 3.1 API for use in these subset EE profiles. This will give vendors the flexibility to provide EJB support across a wide variety of EE profiles.

Portable EJB Global JNDI Names
One common source of frustration for developers is the non-portability of the mapping information (e.g. global JNDI names) used to resolve and lookup EJB references. We'll investigate ways to standardize this information so that applications can be deployed without the need for vendor-specific EJB component mappings.

Singletons
A common problem encountered by developers is how to portably share state between the EJB components in an application. In contrast, the web container has always provided this capability via properties on the ServletContext. A new Singleton bean type will allow for easy sharing of state within the entire application.

Application Initialization and Shutdown Events
EJB applications often need to perform tasks at the point that the application is initializing and/or shutting down. These lifecycle callbacks are supported in the web tier but have never been available directly within the EJB component model.

EJB Timer Service Enhancements
The two most commonly requested new EJB Timer Service features are calendar-based timer expressions and the ability to have an EJB timer created automatically as a result of deployment.

Simple Asynchrony
The main option available to EJB developers who are interested in adding asynchrony to their applications is the JMS API. The combination of JMS messages and message-driven beans is commonly used both as a form of communication between components in collocated applications and as a way to achieve parallelism for local task processing. This approach is cumbersome due to the associated configuration requirements and relative complexity of a messaging API. We plan to address this by integrating simple and lightweight asynchronous capability into the session bean component model.

This blog copyright 2009 by Ken Saks