3 Replies Latest reply on May 9, 2014 8:25 AM by Kevin Stone

    EJB Lookup on remote server then local server

    Kevin Stone Newbie

      If we have 3 jars, Test.jar, Test2.jar, and Test3.jar on our local server running Jboss 7.2.  On a remote server we have Test2.jar.

      From the local server Test.jar needs to invoke a bean in Test2.jar on the remote server then invoke a bean in Test3.jar on the local server.  How can this be done?  I have the Remote lookup working thanks to Wolf-Dieter Fink but I cant get the second lookup to work. It gets a "No EJB receiver available" error.

       

      I set up the remote and local servers following the server instance tutorial (added stuff to standalone-full.xml).

       

      I use exclude-local-receivers in my jboss-ejb-client.xml so I lookup Test2 on the remote server instead of the local server.  This is what causes me not to be able to lookup Test3.jar but I cant remove it because it also allows me to look up the remote Test2.jar.

       

      BeanClient.java  (looks up the remote bean and then the local bean.)

      package org.kd.test;
      import org.kd.test2.Bean;
      import org.kd.test2.BeanRemote;
      import org.kd.test3.Bean3;
      import org.kd.test3.Bean3Remote;
      import org.kd.utilities.ejb.EjbLookup;
      import org.apache.log4j.Logger;
      public class BeanClient {
        private static final Logger log = Logger.getLogger(BeanClient.class);
        BeanRemote remoteBean;
        
        public void callRemoteBean (String inputString) {
           BeanRemote remoteBean = null;
           try {
               Object returnObj = EjbLookup.lookupEjbWithRetry(Bean.class, BeanRemote.class, 0);
               remoteBean = (BeanRemote) returnObj;
               if (remoteBean == null) {
                  log.error("remoteBean not found");
               }
               else {
                  remoteBean.beanTest(inputString);
               }
           }
           catch (Exception ex) {
              ex.printStackTrace();
           }
           Bean3Remote remoteBean3 = null;
           try {
              Object returnObj = EjbLookup.lookupEjbWithRetry(Bean3.class, Bean3Remote.class, 0);
              remoteBean3 = (Bean3Remote) returnObj;
              if (remoteBean3 == null) {
                   log.error("remoteBean3 not found");
              }
              else {
                   remoteBean3.beanTest(inputString);
              }
           }
           catch (Exception ex) {
              ex.printStackTrace();
           }
        }
      }
      
      
      

       

      EjbLookup.java (does the lookup)

      package org.kd.utilities.ejb;
      import java.lang.annotation.Annotation;
      import java.nio.file.Paths;
      import java.util.Properties;
      import javax.ejb.Local;
      import javax.naming.Context;
      import javax.naming.InitialContext;
      import javax.naming.NamingException;
      import org.apache.log4j.Logger;
      public class EjbLookup {
         private static final Logger log = Logger.getLogger(EjbLookup.class);
         private static Object getEjb (Class<?> remoteBean, Class<?> remoteInterface, String earName) throws NamingException {
            Properties env = new Properties();
            env.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
            env.put("jboss.naming.client.ejb.context", "true");
            Context context = new InitialContext(env);
            if (earName == null) {
             earName = "";
            }
            if (earName.length() > 0) {
              log.info("The app name is " + earName);
            }
            // This is the module name of the deployed EJBs on the server. This is typically the jar name of the
            // EJB deployment, without the .jar suffix, but can be overridden via the ejb-jar.xml
            String moduleName = Paths.get(remoteBean.getProtectionDomain().getCodeSource().getLocation().getFile()).getFileName().toString();
            log.info("The module name is " + moduleName);
            moduleName = moduleName.substring(0, moduleName.lastIndexOf('.'));
            // Get remote bean name and interface.  Set the default lookup string for a remote bean
            String remoteBeanName = remoteBean.getSimpleName();
            String remoteInterfaceName = remoteInterface.getName();
            String lookupString = "ejb:" + earName + "/" + moduleName + "//" + remoteBeanName + "!" + remoteInterfaceName;
            //Check for a local bean annotation in the interface and change the lookup accordingly
            try {
               Annotation[] annotations = remoteInterface.getAnnotations();
               for (Annotation annotation: annotations) {
                  log.info("Annotation is " + annotation.toString());
                  if (annotation instanceof Local) {
                       lookupString = "java:global/" + earName + "/" + moduleName + "//" + remoteBeanName + "!" + remoteInterfaceName;
                       break;
                  }
               }
            }
            catch (Exception ex) {
                log.error("Error getting annotations for " + remoteInterfaceName);
            }
            log.info("lookup " + lookupString);
            // let's do the lookup
            Object returnObject = null;
            try {
             returnObject = context.lookup(lookupString);
            }
            catch (Exception ex) {
               ex.printStackTrace();
            }
            context.close();
            log.info("Return the lookup object " + returnObject);
            return returnObject;
         }
      
         private static Object getEjbWithRetry(Class<?> remoteBean, Class<?> remoteInterface, String earName, Integer maxRetries) throws NamingException{
            Object retVal = null;
            Integer curAttempt = -1;
            while ((curAttempt < maxRetries) && (retVal == null)) {
              log.info("Call EJB with " + remoteBean.getName() + " and " + remoteInterface);
              retVal = getEjb(remoteBean, remoteInterface, earName);
              curAttempt++;
            }
            return retVal;
         }
         // Lookup an Stateless EJB that is not in your jar file using the remoteBean class and the remoteInterface class
         public static Object lookupEjbWithRetry(Class<?> remoteBean, Class<?> remoteInterface, Integer maxRetries) {
            Object retVal = null;
            try {
               retVal = getEjbWithRetry(remoteBean, remoteInterface, "", maxRetries);
            }
            catch (Exception ex) {
             ex.printStackTrace();
            }
            return retVal;
         }
      
         // Lookup an Stateless EJB that is not in your jar file using the remoteBean name and the remoteInterface name
         // Use this method if if your class is in an EAR
         public static Object lookupEjbWithRetry(Class<?> remoteBean, Class<?> remoteInterface, String earName, Integer maxRetries) {
            Object retVal = null;
            try {
               retVal = getEjbWithRetry(remoteBean, remoteInterface, earName, maxRetries);
            }
            catch (Exception ex) {
               ex.printStackTrace();
            }
            return retVal;
         }
      }
      
      
      

       

      Now the two simple beans, first the remote bean

       

      BeanRemote.java (the interface for the remote bean)

      package org.kd.test2;
      import javax.ejb.Remote;
      @Remote
      public interface BeanRemote {
          public void beanTest(String inputString);
      }
      
      
      

       

      Bean.java (the remote bean)

      package org.kd.test2;
      import java.io.IOException;
      import java.nio.file.Files;
      import java.nio.file.Path;
      import java.nio.file.Paths;
      import javax.ejb.Stateless;
      import org.apache.log4j.Logger;
      import org.jboss.ejb3.annotation.Pool;
      @Stateless
      @Pool(value="mymodel-pool")
      public class Bean implements BeanRemote {
          private static final Logger log = Logger.getLogger(Bean.class);
          public void beanTest(String inputString) {
              log.info(inputString);
              Path target = Paths.get("/home/redhat/Test.txt");
              try {
                  @SuppressWarnings("unused")
                  Path file = Files.createFile(target);
              }
              catch (IOException ex) {
                  ex.printStackTrace();
              }
          }
      }
      
      
      

       

      And the local bean

       

      Bean3Remote.java

      package org.kd.test3;
      
      import javax.ejb.Remote;
      @Remote
      public interface Bean3Remote {
          public void beanTest(String inputString);
      }
      
      
      

       

      Bean3.jara

      package org.kd.test3;
      import java.io.IOException;
      import java.nio.file.Files;
      import java.nio.file.Path;
      import java.nio.file.Paths;
      import javax.ejb.Stateless;
      import org.apache.log4j.Logger;
      import org.jboss.ejb3.annotation.Pool;
      @Stateless
      @Pool(value="mymodel-pool")
      public class Bean3 implements Bean3Remote {
          private static final Logger log = Logger.getLogger(Bean3.class);
          public void beanTest(String inputString) {
              log.info(inputString);
              Path target = Paths.get("/home/redhat/Test3.txt");
              try {
                  @SuppressWarnings("unused")
                  Path file = Files.createFile(target);
              }
              catch (IOException ex) {
                  ex.printStackTrace();
              }
          }
      }