About Mike Miller

Mike is a software developer who loves to learn how things work. A Java programmer who caught the Groovy & Grails itch and is always looking for opportunities to include them as part of the solution.

JBoss AS7 JNDI & EJB 3.1 Naming changes

As a result of the “feature train” continuing to march on and us not keeping our software stack up-to-date, our team finds ourselves in the un-enviable position of having to migrate:

  • JBoss 4.2.3 to AS 7.1.x (currently looking at 7.1.1)
  • EJB 2.1 to EJB 3.1
  • Hibernate 2 to Hibernate 3 or 4

in quick fashion.  I mean, who wants to ship a new release with 8-10 year old software, not me! The following is the result of some research I did while looking at upgrading from JBoss 4.2.3 with EJB 2.1 to AS 7.1.x with EJB 3.1.  I am sure there will be more
 
posts related to this migration in the near future, but this one is related to changes in the JNDI naming area.

In the past/current

In our current code, the JNDI naming has been very simple:

  1. We concatenated ”ejb/” with the name of the remote Session Bean interface in the deployment descriptor to indicate the name that the service should be bound to.
  2. In the code, we use the following code to handle the JNDI lookup.  The really nice part was that the same code could be used by remote clients AND on the server, within the container.

Current Code

Hashtable properties = new Hashtable();
properties.put("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
properties.put("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
properties.put("java.naming.provider.url", "jnp://localhost:1099");
Context ctx = new InitialContext(properties);
Object ref = ctx.lookup(jndiName);

AS7 and EJB 3.1

The EJB 3.1 spec has made some changes to mandate portable JNDI names for EJBs and you inherit this in AS 7.1.1.   The other tricky thing I found was that I could no longer use the exact same lookup code from our remote clients and the server.

AS 7 now has two options for remote EJB invocation.  The information you need can be found in the JBoss docs, it just didn’t hit me over the head!  After struggling with this issue for a couple days, I decided to create a small program to help make the differences (hopefully) very clear.  Below is the program that I created to invoke a stateless session bean from a remote client.   I deployed the “ejb-remote” sample from the 7.1 Quick Start samples.  The code attempts to load the remote service using both remote methods.  The expectation is that for the first set of lookups, the first lookup is successful and the second, using the “ejb:/” naming format fails.  Then I add the Context.URL_PKG_PREFIXES property with a value of “org.jboss.ejb.client.naming” to the jndi properties passed to the InitialContext constructor and repeat the lookups.  Now, both lookups should be successful.  I have included all the JNDI properties in the code rather than relying on a copy of “jboss-ejb-client.properties” or “jndi.properties” being picked up from the classpath.

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import java.util.Hashtable;

public class EJBClient {

     private static String[] JNDINAME = {
          "jboss-as-ejb-remote-app/CalculatorBean!org.jboss.as.quickstarts.ejb.remote.stateless.RemoteCalculator", 
          "ejb:/jboss-as-ejb-remote-app/CalculatorBean!org.jboss.as.quickstarts.ejb.remote.stateless.RemoteCalculator" 
     };

     private Hashtable jndiProps;

     public EJBClient() {
       // setup 'base' jndi properties - no jboss-ejb-client.properties being picked up from classpath!
       jndiProps = new Hashtable();
          jndiProps.put("java.naming.factory.initial",
"org.jboss.naming.remote.client.InitialContextFactory");
          jndiProps.put(InitialContext.PROVIDER_URL, "remote://localhost:4447");
          jndiProps.put("jboss.naming.client.ejb.context", true);

          // needed for remote access - remember to run add-user.bat
          jndiProps.put(Context.SECURITY_PRINCIPAL, "client");
          jndiProps.put(Context.SECURITY_CREDENTIALS, "password");
     }

    public void doLookups() {
         // the 'exported' namespace
         for (int i = 0; i < JNDINAME.length; i++) {
               lookup(JNDINAME[i]);
          }

         // This is an important property to set if you want to do EJB invocations via the remote-naming project
        jndiProps.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");

        // now with the ejb
        for (int i = 0; i < JNDINAME.length; i++) {
               lookup(JNDINAME[i]);
          }
    }

    private void lookup(String name) {
         System.out.println("Lookup name="+name);

         Context ctx = null;
        try {
               ctx = new InitialContext(jndiProps);
               Object ref = ctx.lookup(name);
               System.out.println("...Successful");
          } catch (NamingException e) {
               System.out.println("...Failed");
               //System.out.println(e.getMessage());
               e.printStackTrace();
          } finally {
               if (ctx != null) {
                    try {
                         ctx.close();
                    } catch (NamingException e) {}
               }
          }
    }

    public static void main(String[] args) throws Exception {
         EJBClient client = new EJBClient();
         client.doLookups();

         System.out.println("Done!");
    }

}

AS7 on the server-side

Now the easy part, doing the JNDI lookups on the server are very similar to the old way, except that you still need to format the JNDI name according to the new specs and the naming factory is no longer the jnp version!

Hashtable jndiProps = new Hashtable();
    jndiProps.put("java.naming.factory.initial", "org.jboss.as.naming.InitialContextFactory");
    ctx = new InitialContext(jndiProps);
    Object ref = ctx.lookup(jndiName);

Conclusion

As I said earlier, the information was/is in the JBoss documentation, but I probably read past it several times.  What I was looking for was an example showing loading the EJBs from both the client and the server.

Hope this helps!
 

Related Whitepaper:

Java Application Development on Linux

Linux is the fastest-growing Java development platform because it saves money and time by serving as a platform for both development and deployment. But developers face significant platform-specific challenges when managing and deploying Java applications in a controlled production environment.

This is the hands-on guide to the full Java application development lifecycle on Linux. It demonstrates the platform, tools, and application development by showing realistic, easy-to-follow examples. After a simple command-line application introduces basic tools, this program leads readers through business-logic object analysis, database design, Java servlet UIs, Java Server Pages (JSP) UIs, Swing GUIs, and Standard Widget Toolkit (SWT) GUIs. Scaling up to the enterprise level provides the opportunity to use both the JBoss Application Server and the Apache Geronimo Application Servers, and Enterprise JavaBeans (EJB).

Get it Now!  

Leave a Reply


seven − = 2



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books