< Java
Tip >
how I came to love portable JNDI names
Harry Klerks
So what are portable JNDI names and how do they work?

Portable JNDI names were introduced in Java EE 6 and do pretty much what their name suggests, making your JNDI names portable from one Java EE implementation to any other. Using them makes you less prone to migration headaches with regards to JNDI naming. Part of the Java EE specification is a naming convention that goes like this.

Part of this naming convention are three JNDI namespaces and the syntax for lookups in that namespace:

  • java:global

    Use this namespace to find remote enterprise beans in a portable way.
    Syntax: java:global[/application name]/module name/enterprise bean name[/interface name]

  • java:module

    Use this namespace to look up local enterprise beans within the same module.
    Syntax: java:module/enterprise bean name/[interface name]

  • java:app

    Use this namespace to look up local enterprise beans packaged within the same application. That is, the enterprise bean is packaged within an EAR file containing multiple Java EE modules.
    Syntax: java:app[/module name]/enterprise bean name[/interface name]

What about non-portable JNDI names then?

Every Java EE server that implements the Java EE 6 specification or later, is supposed to have some support for portable JNDI names. I don't really know about other servers, but GlassFish/Payara fully supports the portable JNDI naming conventions, as you may expect from the Java EE reference implementation. Looking in your server log may learn you a thing or two about the JNDI names that your application server assigns to all sorts of resources, portable and non-portable alike. My advice would be to use the portable naming if at all possible. It can save you serious migration headaches should you come to that. And of course you never will. Yeah right...

Example

Looking up a remote EJB from a standalone client (fragment)

try {

   InitialContext theInitialContext = new InitialContext();

   assortmentBoundary = (AssortmentBoundary) theInitialContext.lookup("java:global/assortment-application/assortment-boundary-ejb/AssortmentBoundaryBean");

} catch (NamingException nex) {

   nex.printStackTrace();

}

This code fragment is taken from the Java fixture of a set of integration tests that run against a running application on a Payara server on the localhost, listening on all the standard ports.

If the application that contains the remote EJB that you're after runs on some other host and/or that other host is using a different set of port numbers, you will have to configure that InitialContext accordingly, otherwise the default values should work.

@Remote(AssortmentBoundary.class)

@Stateless

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)

public class AssortmentBoundaryBean implements AssortmentBoundary {

What you see here is just a standard Stateless Session Bean that has been annotated to indicate that all public methods are available to remote clients. Remote in this context means outside the EAR in which this EJB has been packaged and deployed. The remote client may run in another JVM, but that does not make it remote as such.