SessionBean ServiceManager for lookup and remote calls

Version 1

     

     

    Here is a example of my way to lookup stateful/stateless SessionBeans.  Used in a Singleton for example in a SWT Client it’s possible to execute the lookup for the SessionBeans on start of application and request the required methods of the remote interface in an easy way.

    The core of my implementation is the “ServiceManager.java” class. On the constructor of the ServiceManager will all required stateful/statelass SessionBean classes commited. To get the remote interface of the required session bean simple call the getService(…) method. (A complete example of usage you’ll see on end of this entry).

    1. Implementation

    "ServiceManager.java"

    package org.ts.core.service.manager;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.lang.annotation.Annotation;
    import java.util.HashMap;
    import java.util.InvalidPropertiesFormatException;
    import java.util.Properties;
    import java.util.Set;
    
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    
    import org.apache.log4j.Logger;
    
    /**
     * Class to load SessionBeans
     *
     * @author Tobias Steidle
     * @version 1.0
     */
    public class ServiceManager{
         
         private final static String JNDI_KEY_SERVER_NAME = "ts.j2ee.server.jar";
         
         private final static Logger fLogger = Logger.getLogger(ServiceManager.class);
         private InitialContext fInitalContext = null;
         private HashMap<Class<?>, Object> fServicemap = new HashMap<Class<?>, Object>();
         private String fJ2EEServerName = null;
         
         /**
          * Costructor for ServiceManager
          * 
          * @param aServicesToLoad Array with all required SessionBean Classes
          * 
          */
         public ServiceManager(Class<?> [] aServicesToLoad) {     
              if(aServicesToLoad != null) {
                   for(Class<?> aClass : aServicesToLoad) {
                        if(checkServiceBean(aClass) == true) {                    
                             fServicemap.put(aClass, null);
                        }
                   }               
              } 
              
              if(loadJNDIProperties() == true) {
                   lookupServices();
              } else {
                   fLogger.error("Cannot load JNDI Settings");
              }
              
              
         }
         
         /**
          * Method to check if Class is a Stateful/Stateles Session Bean
          * 
          * @param aClass Class to check
          * 
          * @return true or false if Class is a SessionBean or not
          * 
          */
         private boolean checkServiceBean(Class<?> aClass) {
              boolean lResult = false;
              
              if(aClass != null) {
                   boolean lEJBAnnotationFound = false;
                   Annotation [] lAnnotations = aClass.getAnnotations();
                   for(Annotation lAnnotation : lAnnotations) {
                        Class<?> lAnnotationType = lAnnotation.annotationType();
                        
                        if(( lAnnotationType == javax.ejb.Stateless.class ) || ( lAnnotationType == javax.ejb.Stateful.class )) {
                             lEJBAnnotationFound = true;
                             break;
                        }
                   }
                   
                   if(lEJBAnnotationFound == false) {
                        fLogger.error("Error on load EJB '" + aClass.getName() + "'.\n" +
                                  "This EJB is has no Stateful/Stateless anotation..\n" +
                                  "Maybe it's not an EJB.");
                   } else {
                        lResult = true;
                   }               
              }          
              
              return lResult;
         }
    
         /**
          * Method to load JNDI Settings
          * 
          * @return true or false if JNDI Einstellungen successful loaded or not
          * 
          */
         private boolean loadJNDIProperties() {
              boolean lResult = false;
              
              Properties lJNDIProperties = new Properties();
              File lFile = new File("jndi.properties");
              if(lFile.exists() == true) {
                   try {
                        lJNDIProperties.loadFromXML(new FileInputStream((lFile)));                                        
                        fInitalContext = new InitialContext(lJNDIProperties);
                        
                        Object lObjServerName = lJNDIProperties.get(JNDI_KEY_SERVER_NAME);
                        if(lObjServerName != null) {
                             fJ2EEServerName = lObjServerName.toString();
                             lResult = true;
                        } else {
                             fLogger.error("Key: '" + JNDI_KEY_SERVER_NAME + "' in jndi.properties nicht gefunden.");     
                        }
                        
                        
                   } catch (InvalidPropertiesFormatException e) {
                        fLogger.error(e.getMessage(), e);
                   } catch (FileNotFoundException e) {
                        fLogger.error(e.getMessage(), e);
                   } catch (IOException e) {
                        fLogger.error(e.getMessage(), e);
                   } catch (NamingException e) {
                        fLogger.error(e.getMessage(), e);
                   }
              } else {
                   fLogger.error("JNDI Properties-File 'jndi.properties' not exist");
              }
                   
              return lResult;
         }
         
         /**
          * Method to lookup SessionBeans
          * 
          * @return true or false if lookup is successful or not
          * 
          */
         private boolean lookupServices() {
              boolean lResult = true;
              
              String JNDI_NAMING_LOOKUP_PREFIX = fJ2EEServerName + "/";
              String JNDI_NAMING_LOOKUP_SUFFIX = "/remote";
              
              if(fInitalContext != null) {          
                   if(fServicemap.isEmpty() == false) {
                        Set<Class<?>> lKeySet = fServicemap.keySet();
                        
                        for(Class<?> lKey : lKeySet) {
                             String lFullClassName = lKey.getCanonicalName();
                             if(lFullClassName != null) {
                                  int lIdxPoint = lFullClassName.lastIndexOf('.');
                                  if(lIdxPoint != -1) {                              
                                       String lClassName = lFullClassName.substring(lIdxPoint+1);
                                       String lJNDILookup = JNDI_NAMING_LOOKUP_PREFIX + lClassName + JNDI_NAMING_LOOKUP_SUFFIX;
    
                                       try {
                                            Object lBean = fInitalContext.lookup(lJNDILookup);
                                            if(lBean != null) {
                                                 fServicemap.put(lKey, lBean);
                                            } else {
                                                 lResult = false;
                                            }                                        
                                       } catch (NamingException e) {                                        
                                            fLogger.error(e.getMessage(), e);
                                            lResult = false;
                                       }                                   
                                  }     
                             }                         
                        }          
                        
                   } else {
                        fLogger.error("No Sessionbean to lookup defined");
                        lResult = false;
                   }          
              } else {
                   fLogger.error("Cannot load InitialContext");
                   lResult = false;
              }
              
              return lResult;
         }
                   
         /**
          * Method to get SessionBean Remote Interface
          * 
          * @param aClass Class of required Session bean
          * 
          * @return Remote Interface of required Session bean
          * 
          */
         public <T> T getService(Class<T> aClass) {
              Object lObjService = fServicemap.get(aClass);
              
              if(lObjService == null) {
                   checkServiceBean(aClass);
              } else {
                   return (T)lObjService;     
              }
                             
              return null;
         }
         
    }
    

     

    2. Example Code of a stateful session bean for test

    Example "jndi.properties" file:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
    <properties>
    <entry key="ts.j2ee.server.jar">Example_Application</entry>
    <entry key="java.naming.provider.url">jnp://localhost:1099</entry>
    <entry key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</entry>
    <entry key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</entry>
    <entry key="jnp.socket.Factory">org.jnp.interfaces.TimedSocketFactory</entry>
    </properties>
    

     

    Example "SessionTestRemote.java": (Remote Inferface for Stateles Session Bean)

    package org.ts.server.sessionbeans.remote;
    
    import javax.ejb.Remote;
    
    @Remote
    public interface SessionTestRemote {
         
         public int test() throws Exception;     
    }
    

     

     

    Example "SessionTestRemote.java": (Remote Inferface for Stateles Session Bean)

    package org.ts.server.sessionbeans;
    
    import javax.ejb.Stateless;
    import org.ts.server.sessionbeans.remote.SessionTestRemote;
    
    @Stateless
    public class SessionTestServiceBean implements SessionTestRemote {
    
         public int test() throws Exception {          
              return 0;
         }
    }
    

     

    3. Usage of ServiceManager on a client


    package org.ts.client;
    
    import org.ts.core.service.manager.ServiceManager;
    import org.ts.server.sessionbeans.SessionTestServiceBean;
    import org.ts.server.sessionbeans.remote.SessionTestRemote;
    
    public class main {
    
         public static void main(String[] args) {
              /* Step 1: lookup session beans
                 Call the constructor of ServiceManager with all required Session bean classes */
              ServiceManager lServiceManager = new ServiceManager(new Class<?>[]{SessionTestServiceBean.class});
              /* Step 2: request the required remote interface
                 Call getService(...) method with required session bean class name */
              SessionTestRemote lRemoteInterface = lServiceManager.getService(SessionTestServiceBean.class);
    
              /* Step 3: call the remote test() method */          
              int lResult = lRemoteInterface.test();
              
              /* Step 4: print result to console */
              System.out.println(lResult);
         }
    }
    

     

     

    I hope this is helpful for you.

    Commentaries and suggestions to this entry are welcome.