HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

"Getting All Your Beans from One Bag"
Vol. 5, Issue 10, p. 56

	


Listing 1

micah/util/UID.java

import java.util.*; 
import java.lang.reflect.*; 
import javax.ejb.*; 
import javax.naming.*; 

/** 
* A general purpose EJB factory.  If you wanted to  
* use the abstract factory design pattern here, you could 
* have this class implement a generic interface to provide 
* a higher degree of abstraction.  That level of abstraction 
* was not really needed for this example.  
*/ 

public class EJBFactory { 
   private JNDIFinder _jndiFinder = null; 
   
   /** This constructor sets the JNDIFinder to use.  The JNDIFinder class is  
   * a wrapper around JNDI functionality such as object lookups.  
   */ 
   public EJBFactory(JNDIFinder finder) { 
      setJNDIFinder(finder); 
   } 
    
   /** Method to get the home interface for an EJB with 
   * the specified JNDI name.  The method it uses for lookup 
   * is through a helper JNDIFinder object.
   * 
   * @param jndiName  The name of the EJB object to get 
   * @return An Object that is the home interface 
   * @throws javax.naming.NameNotFoundException if the 
   *         name does not exists in JNDI.  Also throws 
   *         javax.naming.NamingException if there is  
   *         a problem in looking up the name. 
   *  
   */ 
   public Object getHomeInterface(String jndiName) throws 
      javax.naming.NameNotFoundException, 
      javax.naming.NamingException 
   { 
      Object obj = null; 
      obj = _jndiFinder.lookup(jndiName); 
      return obj; 
   } 

   /** Method to create an enterprise bean.  Right now the 
   * Vector of params is getting reflected to determine their  
   * class type. 
   * This might be an expensive operation and so we might  
   * want to use something more efficient in the future to 
   * speed things up.  The important thing to remember is 
   * that ORDER IS IMPORTANT for these parameters.  Otherwise 
   * if you have a create method that takes multiple parame-
   * ters of the same type, then you will get the method 
   * invocation wrong. 
   * 
   * @param jndiName  The JNDI name of the EJB 
   * @param params    A vector containing the arguments to 
   * the create method. 
   * @return An EJBObject that references the remote inter
   * face for the specified EJB runtime instance.  It is safe 
   * to down cast this reference to a specific remote inter
   * face type. 
   * @throws InvocationTargetException or IllegalAccessExcep-
   * tion if the method has trouble invoking the create 
   * method.  See the java.lang.reflect.Method class for 
   * details on these exceptions.  Also throws javax.naming.*   
   * exceptions if there is a lookup failure of the home 
   * interface of the specified EJB.   A RemoteException is 
   * thrown per standard EJB rules.  Throw a generic excep-
   * tion so that any subclasses (e.g. wrappers) can  throw 
   * their own exceptions. 
   */ 
   public EJBObject createBean( String jndiName, Object      
                              []params) 
      throws InvocationTargetException, 
      IllegalAccessException, 
      NoSuchMethodException, 
      java.rmi.RemoteException, 
      javax.naming.NamingException, 
      javax.naming.NameNotFoundException, 
      Exception { 
    
      EJBObject bean = null; 
    
      // Get the home interface and its associated Class 
      // object.  We need the Class object for reflection... 
      //  
      Object homeInterface = getHomeInterface(jndiName); 
      Class beanClass = homeInterface.getClass(); 
    
      // Need a class array for the method lookup... 
      // 
      Class[] signature = getSignature(params); 
    
      // Look up the method--throw exception if method not 
      // there. 
      // All create methods in the home interface are named 
      // "create" so search for the create method with the 
      // appropriate  signature 
      // 
      Method createMethod = beanClass.getDeclaredMethod("cre-
       ate",  signature); 
    
      // This is the key.  Here homeInterface is a reference 
      // to a REAL remote object -- i.e. the skeleton class 
      // on the server.  The invocation is done on this spe-
      // cific instance of the remote object created by the 
      // EJB container on the server. 
      // 
      bean = (EJBObject) createMethod.invoke(homeInterface,  
             params); 
   
      return bean; 
   } 
   
   /** Method to construct an array of Class objects repre-
   * senting a method signature 
   * 
   * @param parameters  A vector whose elements will be 
   * reflected or their specified Classes. 
   * @return A Class array  
   *  
   */ 
   private Class[] getSignature(Object [] parameters) { 
      Class sig[] = new Class[parameters.length]; 
   
      for(int i =0; i<sig.length; i++) { 
         sig[i] = parameters[i].getClass(); 
      } 
      return sig; 
   } 
      
   /** Method to set the internal JDNIFinder variable */ 
   private void setJNDIFinder(JNDIFinder finder) { 
      jndiFinder = finder; 
   } 
}

Listing 2

package com.myapp.util; 

import java.util.*; 
import javax.naming.*; 

/* 
* Class to wrap the EJBFactory to handle the number of exceptions 
* that the factory throws.  By wrapping the factory, it is easier to use 
* its functionality in application code.  
*/ 
public class FactoryWrapper extends EJBFactory { 

/* Method to create an enterprise bean. */ 
public EJBObject createBean( String jndiName, Object []params) 
   throws  AppException 
   { 
      EJBObject bean = null; 
  
      try { 
         bean = super.createBean(jndiName, params); 
     
      } catch (InvocationTargetException e) { 
         throw new AppException(e.getMessage()); 
      } catch (NoSuchMethodException e) { 
         throw new AppException(e.getMessage()); 
      } catch (IllegalAccessException e) { 
         throw new AppException(e.getMessage()); 
      } catch (javax.naming.NameNotFoundException e) { 
         throw new AppException(e.getMessage()); 
      } catch (javax.naming.NamingException e) { 
         throw new AppException(e.getMessage()); 
      } catch (java.rmi.RemoteException e) { 
         throw new AppException(e.getMessage()); 
      } catch (Exception e) { 
         throw new AppException(e.getMessage()); 
      } 
    
      return bean; 
      } 
}

Listing 3

/* Code example to create a bean using a create method 
 * that has a signature of create(String).  This example 
 * uses the FactoryWrapper class from Code Example 2.  
 * 
 * The JNDIFinder class mentioned is a simple wrapper 
 * around a JNDI context.  The code is not given here 
 * for the sake of brevity. 
 */ 
 
 ... 
 try { 
    FactoryWrapper factory = new FactoryWrapper(); 
    
    // The finder variable is created outside of this scope 
    // 
    factory.setJNDIFinder(finder); 
    
    String username = "Foo"; 
    String jndiName = "com/foo/entity/myAppBean"; 
    Object [] createArgs = { username }; 
    
    myAppBean bean = (myAppBean) factory.createBean(jndiName, 
                    createArgs); 
    bean.doWhatever(); 
    
    } catch (ApplicationException e) { 
    // ... Error handling code ... 
    // 
    } 
...

  
 
 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.