Newsletter sign-up
View all newsletters

Sign up for our Enterprise Java Newsletter

Enterprise Java

Java Tip 118: Utilize the EjbProxy

Invoke remote EJBs with a simple utility class

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
If you've ever worked with Enterprise JavaBeans (EJB), you've probably written code to access the EJB from the client program or written code to access it from another EJB. Usually, those code implementations are similar to each other with just a few changes. Good programmers manage to copy and paste most of it (as a kind of code reuse); however, after copying and pasting over the same code several times, it becomes boring. That's why I decided to implement a class that does it for me, called EjbProxy. To keep things clean and simple, this class invokes any EJB without knowing anything more than the EJB's JNDI (Java Naming and Directory Interface) lookup name, and you can use it on the client side or in an EJB.

You must follow four basic steps to invoke an EJB:

  1. Create a JNDI initial context
  2. Look up the EJB name in the context
  3. Get the home object
  4. Create the EJB object's instance via the home object's create() method


The implementation for Steps 1 through 3 is trivial:

    InitialContext ctx = new InitialContext (prop);
    Object home = ctx.lookup(beanName);
    EJBHome obHome =
      (EJBHome) PortableRemoteObject.narrow (home, EJBHome.class);


As you can see, you can obtain the EJB home object without knowing the specific implementation of that particular EJB, except the JNDI name lookup string.

Step 4 is not so straightforward. When you try to create the EJB object using the home object, you can't invoke the create() method from the home object, since the EJBHome interface doesn't define the create() method. Only the actual EJB implementations define and implement this method.

As one possible solution, you could define an interface that extends EJBHome and declares the create() method. Then you could simply cast the home object to this interface and call the create() method. However, this approach has one drawback: it requires all EJBs to implement this particular interface. You'd want to invoke the create() method of an arbitrary home interface.

A better solution would use Java's Reflection API capabilities. (You can refer to Resources for detailed information on the Reflection API.) By using reflection, you can load the specified class using Class.forName, and then call getDeclaredMethod() to retrieve the method the class declares. Once you obtain the Method object, you can execute the method with Method.invoke.

The following code uses reflection to create the EJB object's instance from its home object:

Method m = obHome.getClass().getDeclaredMethod("create", new Class[0]);
Object objRemote = m.invoke (obHome, new Object[0]);
Object obj = PortableRemoteObject.narrow(objRemote, theClass);


That is, this code segment gets the class from the home object, and then calls getDeclaredMethod() with the create() method's name in order to retrieve create's Method object. It also uses the invoke() method to execute the create() method, which returns the EJB object's instance.

The EjbProxy class

The EjbProxy class, found in the source code's EjbProxy.java, manages these nasty details for you.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources