7 Replies Latest reply on Sep 6, 2018 7:35 AM by ckoelle

    Lookup of stateful session bean from second application in same Wildfly instance

    ckoelle

      Hi

       

      I have a problem with calling a stateful session bean remotely from another application deployed in the same Wildfly (12.0.0.Final) instance.

       

      The first application (backend application) contains the stateful bean:

       

      package ch.nic.reg.backend;

       

      import javax.ejb.Stateful;

       

      import ch.nic.reg.common.BackendRemote;

       

      @Stateful

      public class EPPBackendBean implements EPPBackendRemote {

       

           public String getSessionId() throws Exception {

                return "NewSessionId123";

           }

       

       

      The bean is inside an ejb-jar and packed in an ear. The ear deploys fine in the server:

       

       

      08:43:14,778 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-5) WFLYEJB0473: JNDI bindings for session bean named 'BackendBean' in deployment unit 'subdeployment "backend.jar" of deployment "backend.ear"' are as follows:

       

      java:global/backend/backend/BackendBean!ch.nic.reg.common.BackendRemote

      java:app/backend/BackendBean!ch.nic.reg.common.BackendRemote

      java:module/BackendBean!ch.nic.reg.common.BackendRemote

      java:jboss/exported/backend/backend/BackendBean!ch.nic.reg.common.BackendRemote

      java:global/backend/backend/BackendBean

      java:app/backend/BackendBean

      java:module/BackendBean

       

      The second application (frontend application) has a singleton bean which calls the backend bean:

       

      @Singleton

      @Startup

      public class Frontend {

       

      @PostConstruct

      public void start() {

           InitialContext context = null;

           Backend remote = null;

           try {

           Map<String, String> environment = new Hashtable<>();

           environment.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory");

           environment.put(Context.PROVIDER_URL,"http-remoting://localhost:8080");

           context = new InitialContext((Hashtable<String, String>) environment);

           remote = (BackendRemote) context.lookup("ejb:backend/backend/BackendBean!ch.nic.reg.common.BackendRemote?stateful");

           } catch (Exception e) {

                e.printStackTrace();

           }

           }

      }

       

      In order to ensure that the backend is deployed before the singleton bean starts we have a dependency between the two deploments defined in jboss-all.xml in frontend ear:

       

      <jboss umlns="urn:jboss:1.0">

           <jboss-deployment-dependencies xmlns="urn:jboss:deployment-dependencies:1.0">

                <dependency name="reg-epp-backend-client.ear" />

           </jboss-deployment-dependencies>

      </jboss>

       

      Additionaly the frontend ear has also a wildfly-config.xml:

       

      <configuration> 

          <authentication-client xmlns="urn:elytron:1.0">

              <authentication-rules>

                          <rule use-configuration="default" />

              </authentication-rules>

              <authentication-configurations>

                  <configuration name="default">

                      <sasl-mechanism-selector selector="#ALL" />

                      <set-mechanism-properties>

                          <property key="wildfly.sasl.local-user.quiet-auth" value="true" />

                       </set-mechanism-properties>

                      <providers>

                          <use-service-loader/>

                      </providers>

                   </configuration>

              </authentication-configurations>

          </authentication-client>

      </configuration> 

       

      Here's the error message:

       

      08:43:19,915 ERROR [stderr] (ServerService Thread Pool -- 75) javax.naming.CommunicationException: EJBCLIENT000062: Failed to look up "backend/backend/BackendBean!ch.nic.reg.common.BackendRemote?stateful" [Root exception is org.jboss.ejb.client.RequestSendFailedException: EJBCLIENT000409: No more destinations are available]

      08:43:19,916 ERROR [stderr] (ServerService Thread Pool -- 75) at org.jboss.ejb.client.EJBRootContext.lookupNative(EJBRootContext.java:160)

      ....

      08:43:19,925 ERROR [stderr] (ServerService Thread Pool -- 75) Caused by: org.jboss.ejb.client.RequestSendFailedException: EJBCLIENT000409: No more destinations are available

      08:43:19,925 ERROR [stderr] (ServerService Thread Pool -- 75) at org.jboss.ejb.client.NamingEJBClientInterceptor.handleSessionCreation(NamingEJBClientInterceptor.java:100)

       

      If i try to lookup the backend bean from a standalone EJB client with the exact same lookup code it works perfectly.

       

      Any ideas what's the difference?

       

      Christian

        • 1. Re: Lookup of stateful session bean from second application in same Wildfly instance
          jewellgm

          Since the deployments are in the same wildfly instance, is there any reason you don't want to use dependency injection?  Rather than having your @PostConstruct method to lookup the bean, you could annotate the Backend instance like this:

           

          @EJB(lookup="java:global/backend/backend/BackendBean!ch.nic.req.common.BackendRemote")

          Backend remote;

           

          Additionally, by using dependency injection, you wouldn't need to setup the relationship to insure that Backend is deployed before Frontend.  Wildfly will be able to determine the dependency, and make sure everything is deployed in the proper order.

           

          If you do need to use the manual JNDI lookups, you shouldn't need to specify the environment properties because it will automatically perform local lookups.  You would need to replace the lookup string with one of the remote lookup strings that wildfly displays in the console (like the one I used in the DI, above).

          • 2. Re: Lookup of stateful session bean from second application in same Wildfly instance
            ckoelle

            Thanks for the answer.

             

            The frontend and backend application are deployed in the same Wildfly instance only in our development environment. In production these run on different servers. So the dependency injection method is not feasible for us.

             

            The JNDI lookup with the lookup string you mentioned results in the same error message.

             

            BTW: When i try the same setup with a stateless session bean it works fine.

            • 3. Re: Lookup of stateful session bean from second application in same Wildfly instance
              ckoelle

              A follow up:

               

              The above mentioned code and configuration works fine when the two ears are deployed in separate Wildfly 12 (or 11) instances and also with Wildfly 10 and only one instance.

               

              I'm pretty sure that also in the case of deployment in the same Wildfly instance a remote call is necessary. In my understanding there are two separate applications running and the application server isolates them from another (separate class loaders and so on).

              • 4. Re: Lookup of stateful session bean from second application in same Wildfly instance
                jewellgm

                Yes, you will need to use a remote interface according to the EJB spec.  Performing a lookup across deployments requires the use of a remote interface.  Application servers are able to perform internal optimizations, such as not actually serializing data, but that behavior is not guaranteed.

                 

                Have you tried changing the URL protocol from "http-remoting" to "remote+http"?  The "http-remoting" protocol was deprecated as of Wildfly 11.

                 

                [WFCORE-296] Switch URI scheme from remoting:// http-remoting:// https-remoting:// to remote:// remote+http:// and remot…

                • 5. Re: Lookup of stateful session bean from second application in same Wildfly instance
                  ckoelle

                  I do use a remote interface. The use of remote+http changes nothing.

                  • 6. Re: Lookup of stateful session bean from second application in same Wildfly instance
                    ckoelle

                    I tried to reduce the problem to the minimum. I now have two EARs. The first contains the two EJBs, one stateless and one stateful. Both have local and remote interfaces. The second contains a singleton startup bean that tries to lookup and call the EJBs in the post construct method. Here's the code of the calling bean:

                     

                    package ch.nic.reg.wildflytest;

                     

                     

                    import java.util.Hashtable;

                    import java.util.Map;

                     

                     

                    import javax.annotation.PostConstruct;

                    import javax.ejb.LocalBean;

                    import javax.ejb.Singleton;

                    import javax.ejb.Startup;

                    import javax.naming.Context;

                    import javax.naming.InitialContext;

                     

                     

                    /**

                    * Session Bean implementation class FrontendBean

                    */

                    @Singleton

                    @LocalBean

                    @Startup

                    public class FrontendBean {

                     

                     

                    /**

                    * Default constructor.

                    */

                    public FrontendBean() {

                    }

                     

                     

                    @PostConstruct

                    public void init() {

                    System.out.println("Starting Frontend!");

                    InitialContext context = null;

                    StatelessBackendBeanRemote slsb = null;

                    try {

                    Map<String, String> environment = new Hashtable<>();

                    environment.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory");

                    environment.put(Context.PROVIDER_URL, "localhost:8080");

                    context = new InitialContext((Hashtable<String, String>) environment);

                    slsb = (StatelessBackendBeanRemote) context.lookup("java:global/BackendEAR/Backend//StatelessBackendBean!ch.nic.reg.wildflytest.StatelessBackendBeanRemote");

                    } catch (Exception e) {

                    e.printStackTrace();

                    }

                    System.out.println("Remote call to stateless bean: " + slsb.helloRemote());

                    StatefulBackendBeanRemote sfsb = null;

                    try {

                    Map<String, String> environment = new Hashtable<>();

                    environment.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory");

                    environment.put(Context.PROVIDER_URL, "localhost:8080");

                    context = new InitialContext((Hashtable<String, String>) environment);

                    sfsb = (StatefulBackendBeanRemote) context.lookup("java:global/BackendEAR/Backend//StatefulBackendBean!ch.nic.reg.wildflytest.StatefulBackendBeanRemote?stateful");

                    } catch (Exception e) {

                    e.printStackTrace();

                    }

                    System.out.println("Remote call to stateful bean: " + sfsb.helloRemote());

                    }

                     

                     

                    }

                     

                    After deploying both EARs in a Wildfly 11, 12, 13 or 14 this is the result:

                     

                    14:53:32,919 INFO  [org.jboss.weld.deployer] (MSC service thread 1-8) WFLYWELD0003: Processing weld deployment Backend.jar

                    14:53:32,929 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-8) WFLYEJB0473: JNDI bindings for session bean named 'StatefulBackendBean' in deployment unit 'subdeployment "Backend.jar" of deployment "BackendEAR.ear"' are as follows:

                     

                     

                    java:global/BackendEAR/Backend/StatefulBackendBean!ch.nic.reg.wildflytest.StatefulBackendBeanLocal

                    java:app/Backend/StatefulBackendBean!ch.nic.reg.wildflytest.StatefulBackendBeanLocal

                    java:module/StatefulBackendBean!ch.nic.reg.wildflytest.StatefulBackendBeanLocal

                    ejb:BackendEAR/Backend/StatefulBackendBean!ch.nic.reg.wildflytest.StatefulBackendBeanLocal?stateful

                    java:global/BackendEAR/Backend/StatefulBackendBean!ch.nic.reg.wildflytest.StatefulBackendBeanRemote

                    java:app/Backend/StatefulBackendBean!ch.nic.reg.wildflytest.StatefulBackendBeanRemote

                    java:module/StatefulBackendBean!ch.nic.reg.wildflytest.StatefulBackendBeanRemote

                    java:jboss/exported/BackendEAR/Backend/StatefulBackendBean!ch.nic.reg.wildflytest.StatefulBackendBeanRemote

                    ejb:BackendEAR/Backend/StatefulBackendBean!ch.nic.reg.wildflytest.StatefulBackendBeanRemote?stateful

                     

                     

                    14:53:32,929 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-8) WFLYEJB0473: JNDI bindings for session bean named 'StatelessBackendBean' in deployment unit 'subdeployment "Backend.jar" of deployment "BackendEAR.ear"' are as follows:

                     

                     

                    java:global/BackendEAR/Backend/StatelessBackendBean!ch.nic.reg.wildflytest.StatelessBackendBeanRemote

                    java:app/Backend/StatelessBackendBean!ch.nic.reg.wildflytest.StatelessBackendBeanRemote

                    java:module/StatelessBackendBean!ch.nic.reg.wildflytest.StatelessBackendBeanRemote

                    java:jboss/exported/BackendEAR/Backend/StatelessBackendBean!ch.nic.reg.wildflytest.StatelessBackendBeanRemote

                    ejb:BackendEAR/Backend/StatelessBackendBean!ch.nic.reg.wildflytest.StatelessBackendBeanRemote

                    java:global/BackendEAR/Backend/StatelessBackendBean!ch.nic.reg.wildflytest.StatelessBackendBeanLocal

                    java:app/Backend/StatelessBackendBean!ch.nic.reg.wildflytest.StatelessBackendBeanLocal

                    java:module/StatelessBackendBean!ch.nic.reg.wildflytest.StatelessBackendBeanLocal

                    ejb:BackendEAR/Backend/StatelessBackendBean!ch.nic.reg.wildflytest.StatelessBackendBeanLocal

                     

                     

                    14:53:32,929 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-8) WFLYEJB0473: JNDI bindings for session bean named 'StartupBean' in deployment unit 'subdeployment "Backend.jar" of deployment "BackendEAR.ear"' are as follows:

                     

                     

                    java:global/BackendEAR/Backend/StartupBean!ch.nic.reg.wildflytest.StartupBean

                    java:app/Backend/StartupBean!ch.nic.reg.wildflytest.StartupBean

                    java:module/StartupBean!ch.nic.reg.wildflytest.StartupBean

                    ejb:BackendEAR/Backend/StartupBean!ch.nic.reg.wildflytest.StartupBean

                    java:global/BackendEAR/Backend/StartupBean

                    java:app/Backend/StartupBean

                    java:module/StartupBean

                     

                     

                    14:53:32,964 INFO  [org.jboss.weld.Version] (MSC service thread 1-1) WELD-000900: 3.0.5 (Final)

                    14:53:33,224 INFO  [org.infinispan.factories.GlobalComponentRegistry] (MSC service thread 1-7) ISPN000128: Infinispan version: Infinispan 'Estrella Galicia' 9.3.1.Final

                    14:53:33,393 INFO  [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 72) WFLYCLINF0002: Started client-mappings cache from ejb container

                    14:53:34,031 INFO  [stdout] (ServerService Thread Pool -- 74) Local call to stateless session beanHello Local

                    14:53:34,033 INFO  [stdout] (ServerService Thread Pool -- 74) Local call to stateful session beanHello Local

                    14:53:34,076 INFO  [org.jboss.weld.deployer] (MSC service thread 1-4) WFLYWELD0003: Processing weld deployment FrontendEAR.ear

                    14:53:34,095 INFO  [org.jboss.weld.deployer] (MSC service thread 1-1) WFLYWELD0003: Processing weld deployment Frontend.jar

                    14:53:34,098 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-1) WFLYEJB0473: JNDI bindings for session bean named 'FrontendBean' in deployment unit 'subdeployment "Frontend.jar" of deployment "FrontendEAR.ear"' are as follows:

                     

                     

                    java:global/FrontendEAR/Frontend/FrontendBean!ch.nic.reg.wildflytest.FrontendBean

                    java:app/Frontend/FrontendBean!ch.nic.reg.wildflytest.FrontendBean

                    java:module/FrontendBean!ch.nic.reg.wildflytest.FrontendBean

                    ejb:FrontendEAR/Frontend/FrontendBean!ch.nic.reg.wildflytest.FrontendBean

                    java:global/FrontendEAR/Frontend/FrontendBean

                    java:app/Frontend/FrontendBean

                    java:module/FrontendBean

                     

                     

                    14:53:34,250 INFO  [stdout] (ServerService Thread Pool -- 74) Starting Frontend!

                    14:53:34,256 INFO  [org.wildfly.naming] (ServerService Thread Pool -- 74) WildFly Naming version 1.0.9.Final

                    14:53:34,278 INFO  [org.jboss.ejb.client] (ServerService Thread Pool -- 74) JBoss EJB Client version 4.0.11.Final

                    14:53:34,307 INFO  [stdout] (ServerService Thread Pool -- 74) Remote call to stateless bean: Hello Remote

                    14:53:34,311 ERROR [stderr] (ServerService Thread Pool -- 74) javax.naming.NameNotFoundException: global/BackendEAR/Backend//StatefulBackendBean!ch.nic.reg.wildflytest.StatefulBackendBeanRemote?stateful -- service jboss.naming.context.java.global.BackendEAR.Backend."StatefulBackendBean!ch.nic.reg.wildflytest.StatefulBackendBeanRemote?stateful"

                    14:53:34,311 ERROR [stderr] (ServerService Thread Pool -- 74) at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:106)

                     

                    The stateless session bean ist called seccessfully, the stateful cannot be found. What's the difference here? I played around with the PROVIDER_URL with no success.

                    • 7. Re: Lookup of stateful session bean from second application in same Wildfly instance
                      ckoelle

                      It seems that no one has ever had this problem. I created a minimal showcase for this. This can be found here:

                       

                      https://www.dropbox.com/sh/rlcsd569op19bum/AABd0nnGgdJVxTuIjI9JlG21a?dl=0

                       

                      I tried this example with newly downloaded Wildfly12 instances.

                       

                      When deploying BackendEAR.ear in one Wildfly instance and FrontendEAR.ear in a second Wildfly instance (only change in standalone.xml is a port shift in order to start both instances on the same machine) everythings fine. Deploying BackendEAR.ear and LocalFrontendEAR.ear in one Wildfly instance results in the above mentioned error. The only difference between FrontendEAR.ear and LocalFrontendEAR.ear ist a jboss-all.xml in LocalFrontendEAR.ear to ensure that the BackendEAR ist compeltely deployed before starting the LocalFrontendEAR.

                       

                      Maybe someone with more insight has the time to try this out.