Sunday, October 10, 2010

EJB3.1 Global JNDI Access - A portable jndi naming scheme for EJBs

Many of you, who have been using EJBs would know that one of the pain points, with respect to portability, is the JNDI names of the beans. As you all will be aware, prior to EJB3.1 spec, there wasn't a standard portable JNDI naming scheme for EJBs. Each application server had its own JNDI naming scheme, which would often mean that you either had to include a server specific deployment descriptor (jboss.xml for JBoss AS) or use annotations to override the JNDI names (for EJB3.0). So while migrating our project to some other application server, you almost always would end up with NameNotFoundException, if you forgot to configure/change the JNDI names to match the application server you are deploying to.

However, starting EJB3.1, the spec now mandates portable JNDI names for EJBs. The compliant application servers are now expected to bind the EJBs at some pre-defined portable JNDI names. Effectively, when you deploy the same EJB jar into a different compliant application server, you will no longer have to change/configure the JNDI names, if you use the portable JNDI names during lookup.

Syntax of portable JNDI names:

The EJB3.1 spec (section 4.4 "Global JNDI Access") explains the syntax of the portable JNDI names. It's actually more than a couple of lines, with examples. So quoting that section here would be a waste of space. Its better to just download the spec and read through it. But I'll just show some examples of the portable JNDI names, in the next section.

Example of the new JNDI naming scheme:

Let's assume you have the following Stateless EJB:

 
package org.myapp.ejb.impl;

@Stateless
@Remote(Echo.class)
@LocalBean
public class SimpleSLSB implements Echo
{
...
}


The SimpleSLSB exposes a remote business interface view and also (explicitly) marks the bean for the no-interface view. So this bean now has 2 views - the remote business interface view and the no-interface view.

Let's further assume that we are packaging this bean in a simple .jar file and deploying it to the application server. Let's name the jar file myejb3.jar.

As per the EJB3.1 spec, global jndi naming scheme, this bean will now be available at (all of the) following JNDI names:

java:global/myejb3/SimpleSLSB!org.myapp.ejb.impl.Echo
java:global/myejb3/SimpleSLSB!org.myapp.ejb.impl.SimpleSLSB
java:app/myejb3/SimpleSLSB!org.myapp.ejb.impl.Echo
java:app/myejb3/SimpleSLSB!org.myapp.ejb.impl.SimpleSLSB
java:module/SimpleSLSB!org.myapp.ejb.impl.Echo
java:module/SimpleSLSB!org.myapp.ejb.impl.SimpleSLSB



#1 above exposes the remote business interface view in the java:global namespace and #2 exposes the no-interface view (remember, we explicitly marked our bean as @LocalBean) in the java:global namespace. As can be seen, the JNDI name is composed of a namespace (for example java:global), a app/module name (for example myejb3), the bean name, which by default is the unqualified name of the bean implementation class (for example SimpleSLSB) and finally the fully qualified name of the business interface being exposed (for example, org.myapp.ejb.impl.Echo). In case of no-interface view, the final part of the JNDI name is the fully qualified name of the bean implementation class.

The rest of the JNDI names follow the same naming scheme, except that they are available in a different JNDI namespace. More details can be found in the EJB3.1 spec (section 4.4 "Global JNDI Access").

Support for EJB3.1 global JNDI names in JBoss AS:

The current JBoss AS trunk supports this new JNDI naming scheme. So the upcoming JBoss AS 6.0.0.CR1 release will have support for this feature. However, if you want to try it out before JBoss AS 6.0.0.CR1 is released, then you can download the nightly build of JBoss AS from here and give it a try.

Reporting issues:

If you have any questions or run into issue while testing this, then feel free to bring it up in our EJB3 user forum.