4 Replies Latest reply on Nov 10, 2013 12:53 PM by kababji

    Lookup remote EJB from standalone java project

    kababji

      Hi, I am stuck with this problem for almost two days and I cannot figure out what is the problem, here is what I have done:

       

      • downloaded wildfly-8.0.0.Beta1
      • Using the command line tool: bin/add-user.bat created an Application user: user1234 with password: pass1234
      • Created an EAR project in eclipse, this project contains only one remote EJB as follows:

       

      package test;
      
      import javax.ejb.Remote;
      import javax.ejb.Stateless;
      
      @Stateless
      @Remote(Test.class)
      public class TestBean implements Test {
      
        @Override
        public String sayHello() {
        return "Hello World";
        }
      
      }
      
      
      
      

       

      • The project is deployed as an EAR named: test-ear.ear and contains an ejb-jar named: test-ejb.jar the server log shows no errors, and here is the section of the log that shows that the bean was deployed correctly:
      java:global/test-ear/test-ejb/TestBean!test.Test
      java:app/test-ejb/TestBean!test.Test
      java:module/TestBean!test.Test
      java:jboss/exported/test-ear/test-ejb/TestBean!test.Test
      java:global/test-ear/test-ejb/TestBean
      java:app/test-ejb/TestBean
      java:module/TestBean
      
      
      
      

       

      • At this point I created a new standard Java project, the classpath is configured to use the %JBOSS_HOME%/bin/client/jboss-client.jar and the java interface test.Test.
      • In this project I created two classes to try to lookup the remote EJB the first one: TestEJBClient1 is as follows:

       

      package ejbclient;
      
      import java.util.Properties;
      import javax.naming.Context;
      import javax.naming.InitialContext;
      import javax.naming.NamingException;
      
      public class TestEJBClient1 {
      
        public static void main(String[] args) throws NamingException {
      
          Properties env = new Properties();
          env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
          env.put(Context.PROVIDER_URL, "remote://localhost:4447");
          env.put(Context.SECURITY_PRINCIPAL, "user1234");
          env.put(Context.SECURITY_CREDENTIALS, "pass1234");
          env.put("jboss.naming.client.ejb.context", true);
      
          InitialContext ctx = new InitialContext(env);
          System.out.println("context initialized successfully.");
      
          String[] lookups = {
              "ejb:test-ear/test-ejb//TestBean!test.Test"
            , "java:global/test-ear/test-ejb//TestBean!test.Test"
          };
      
          for (String l : lookups) {
            try {
              System.out.println("trying to lookup from: " + l);
              Test test = (Test) ctx.lookup(l);
              System.out.println("lookedup successfully, class is: " + test);
      
              test.sayHello();
            } catch (NamingException e) {
              System.out.println("Failed to lookup using: " + l);
              e.printStackTrace();
            }
          }
      
        }
      }
      
      
      
      

       

      • When I execute this class it fails when I try to lookup the bean, the output of this class is the following:
      log4j:WARN No appenders could be found for logger (org.jboss.logging).
      log4j:WARN Please initialize the log4j system properly.
      log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
      context initialized successfully.
      trying to lookup from: ejb:test-ear/test-ejb//TestBean!test.Test
      Failed to lookup using: ejb:test-ear/test-ejb//TestBean!test.Test
      trying to lookup from: java:global/test-ear/test-ejb//TestBean!test.Test
      javax.naming.NamingException: Failed to connect to any server. Servers tried: [remote://localhost:4447]
        at org.jboss.naming.remote.client.HaRemoteNamingStore.failOverSequence(HaRemoteNamingStore.java:213)
        at org.jboss.naming.remote.client.HaRemoteNamingStore.namingStore(HaRemoteNamingStore.java:144)
        at org.jboss.naming.remote.client.HaRemoteNamingStore.namingOperation(HaRemoteNamingStore.java:125)
        at org.jboss.naming.remote.client.HaRemoteNamingStore.lookup(HaRemoteNamingStore.java:241)
        at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:79)
        at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:83)
        at javax.naming.InitialContext.lookup(InitialContext.java:411)
        at ejbclient.TestEJBClient1.main(TestEJBClient1.java:34)
      Failed to lookup using: java:global/test-ear/test-ejb//TestBean!test.Test
      javax.naming.NamingException: Failed to connect to any server. Servers tried: [remote://localhost:4447]
        at org.jboss.naming.remote.client.HaRemoteNamingStore.failOverSequence(HaRemoteNamingStore.java:213)
        at org.jboss.naming.remote.client.HaRemoteNamingStore.namingStore(HaRemoteNamingStore.java:144)
        at org.jboss.naming.remote.client.HaRemoteNamingStore.namingOperation(HaRemoteNamingStore.java:125)
        at org.jboss.naming.remote.client.HaRemoteNamingStore.lookup(HaRemoteNamingStore.java:241)
        at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:79)
        at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:83)
        at javax.naming.InitialContext.lookup(InitialContext.java:411)
        at ejbclient.TestEJBClient1.main(TestEJBClient1.java:34)
      
      
      
      

       

      • The second class: TestEJBClient2 is as follows:
      package ejbclient;
      
      import java.util.Properties;
      import javax.naming.Context;
      import javax.naming.InitialContext;
      import javax.naming.NamingException;
      import test.Test;
      
      public class TestEJBClient2 {
      
        public static void main(String[] args) throws NamingException {
          Properties env = new Properties();
          env.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
          env.put(Context.PROVIDER_URL, "remote://localhost:4447");
          env.put(Context.SECURITY_PRINCIPAL, "user1234");
          env.put(Context.SECURITY_CREDENTIALS, "pass1234");
          env.put("jboss.naming.client.ejb.context", true);
         
          InitialContext ctx = new InitialContext(env);
          System.out.println("context initialized successfully.");
      
          String l = "ejb:test-ear/test-ejb//TestBean!test.Test";
          try {
            System.out.println("trying to lookup from: " + l);
            Test test = (Test) ctx.lookup(l);
            System.out.println("lookedup successfully, class is: " + test);
      
            test.sayHello();
          } catch (NamingException e) {
            System.out.println("Failed to lookup using: " + l);
            e.printStackTrace();
          }
      }
      }
      
      
      
      
      

       

      • When I execute this class things seems to be better, I get the proxy to the remote EJB, but when I try to invoke the method sayHello() an exception is thrown saying: EJBCLIENT000025: No EJB receiver available for handling
      context initialized successfully.
      trying to lookup from: ejb:test-ear/test-ejb//TestBean!test.Test
      log4j:WARN No appenders could be found for logger (org.jboss.logging).
      log4j:WARN Please initialize the log4j system properly.
      log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
      lookedup successfully, class is: Proxy for remote EJB StatelessEJBLocator{appName='test-ear', moduleName='test-ejb', distinctName='', beanName='TestBean', view='interface test.Test'}
      Exception in thread "main" java.lang.IllegalStateException: EJBCLIENT000025: No EJB receiver available for handling [appName:test-ear, moduleName:test-ejb, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@1970196d
        at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:743)
        at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:116)
        at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:183)
        at org.jboss.ejb.client.EJBInvocationHandler.sendRequestWithPossibleRetries(EJBInvocationHandler.java:253)
        at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:198)
        at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:181)
        at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:144)
        at com.sun.proxy.$Proxy0.sayHello(Unknown Source)
        at ejbclient.TestEJBClient2.main(TestEJBClient2.java:33)
      
      
      
      

       

      Any ideas why I am able to lookup the EJB bean but no able to invoke a method on it? please note that I have no property files in the classpath of the project.

       

      By the way, when JBoss is up and running, using the standalon.xml configuration. If I execute the following command: netstat -nao | grep 4447 I don't see any port equal to 4447, more over searching all XML files under %JBOSS_HOME% I didn't find any configuration related to this port is that normal? the only port configurations I see are the following:

      <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
              <socket-binding name="management-native" interface="management" port="${jboss.management.native.port:9999}"/>
              <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
              <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
              <socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
              <socket-binding name="http" port="${jboss.http.port:8080}"/>
              <socket-binding name="https" port="${jboss.https.port:8443}"/>
              <socket-binding name="txn-recovery-environment" port="4712"/>
              <socket-binding name="txn-status-manager" port="4713"/>
              <outbound-socket-binding name="mail-smtp">
                  <remote-destination host="localhost" port="25"/>
              </outbound-socket-binding>
      </socket-binding-group>
      
      
      
      

       

      Thanks,

      Omar.

        • 1. Re: Lookup remote EJB from standalone java project
          wdfink

          WildFly use the 8080 port by default, all services are routed to the same port.

          Use port 8080 for your ejb-client, that should work

          • 2. Re: Lookup remote EJB from standalone java project
            kababji

            I tried to change the Context.PROVIDER_URL to remote://localhost:8080 and http://localhost:8080 but I still get the exact same errors mentioned above.

            • 3. Re: Lookup remote EJB from standalone java project
              wdfink

              You should not mix different approaches.

              You might have a look to the ejb-remote quickstart

              • 4. Re: Re: Lookup remote EJB from standalone java project
                kababji

                Perfect , now it is working! Just one remark in the tutorial it mentions to use AS7 I tried it with a 7.1.1 and I got errors because the properties file had the port number 8080 instead of 4447, my guess is that the tutorial will be modified in the near future to be for WildFly instead of AS7.

                 

                For the lazy ones or in case the above link doesn't work anymore, here is my final configuration:

                 

                For the client side:

                • Add the jar %JBOSS_HOME%/bin/client/jboss-client.jar
                • Add a file named jboss-ejb-client.properties under the project src directory with the following configurations
                remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
                remote.connections=default
                remote.connection.default.host=localhost
                remote.connection.default.port=8080
                remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
                
                • To lookup the remote bean create the InitialContext as follows:
                final Properties env = new Properties();
                env.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
                final Context ctx = new InitialContext(env);
                

                 

                I have to admit that the first time I tried it I still got the same error (maybe I was blinded!), so I rolled back to a stable version: AS 7 and tried there and once it worked I got back to WildFly, my only change was the port 4447 to 8080 and it worked like charm. During my tests I also changed JRE versions from 7 to 6 and then back to 7.

                 

                Thank you so much Wolf