0 Replies Latest reply on Mar 13, 2012 12:03 PM by steffenwollscheid

    Declared EJB client context not found in OSGi bundles

    steffenwollscheid

      Hi all,

       

      we have a jar which is an OSGi bundle and has a jboss-ejb-client.xml because it uses remote EJBs (which currently happen to be in the same VM).

      According to the log, the META-INF/jboss-ejb-client.xml is processed into a DescriptorBasedEJBClientContextService:

      [Server:server-one] 14:41:16,497 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-2) JBAS015876: Starting deployment of "accsessor-osgi-0.0.1-SNAPSHOT.jar"
      [Server:server-one] 14:41:16,515 DEBUG [org.jboss.as.ejb3.deployment.processors.EJBClientDescriptorMetaDataProcessor] (MSC service thread 1-12) Deployment unit deployment "accsessor-osgi-0.0.1-SNAPSHOT.jar" will 
      use service jboss.ejb3.dd-based-ejb-client-context."accsessor-osgi-0.0.1-SNAPSHOT.jar" as the EJB client context service [Server:server-one] 14:41:16,517 DEBUG [org.jboss.as.ejb3.remote.DescriptorBasedEJBClientContextService] (MSC service thread 1-13) Added a local EJB receiver to descriptor based EJB client context named service jboss.ejb3.dd-based-ejb-client-context."accsessor-osgi-0.0.1-SNAPSHOT.jar" [Server:server-one] 14:41:16,517 DEBUG [org.jboss.as.ejb3.remote.DescriptorBasedEJBClientContextService] (MSC service thread 1-13) Creating remoting EJB receiver for connection remote-ejb-connection [Server:server-one] 14:41:16,525 DEBUG [org.jboss.ejb.client.EJBClientContext] (MSC service thread 1-13) Skipping registration of receiver Remoting connection EJB receiver
      [connection=Remoting connection <1d16a4fa>,channel=jboss.ejb,nodename=master:server-one] since an EJB receiver already exists for node name master:server-one in client context org.jboss.ejb.client.EJBClientContext@61761d82 [Server:server-one] 14:41:16,525 DEBUG [org.jboss.as.ejb3.remote.DescriptorBasedEJBClientContextService] (MSC service thread 1-13) Added 1 remoting EJB receivers to descriptor based EJB client context named
      service jboss.ejb3.dd-based-ejb-client-context."accsessor-osgi-0.0.1-SNAPSHOT.jar"

      Looking up and calling the remote EJB works since 7.1.1-Final (or 7.1.0-Final containing the fix for AS7-3830), but will always run into the default EJB client context (as can be seen in the log):

      [Server:server-one] 16:11:39,901 DEBUG [org.jboss.as.ejb3.remote.TCCLEJBClientContextSelector] (RMI TCP Connection(2)-10.0.103.110) Returning default EJB client context org.jboss.ejb.client.EJBClientContext@14c55d66 
      since no EJB client context could be found for TCCL HostBundleClassLoader for Module "deployment.steffen.experimental.ejb-remote.accsessor-osgi:0.0.1.SNAPSHOT" from Service Module Loader

      Although this is a stateless EJB.

       

      The lookup code is the following:

      RemoteCalculator calc = null;
      Properties props = new Properties();
      props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
      try
      {
           InitialContext ctx = new InitialContext(props);
           System.out.println("doing lookup");
           calc =      
                (RemoteCalculator)ctx.lookup(
                "ejb:application-ear-0.0.1-SNAPSHOT/ejb-definition-0.0.1-SNAPSHOT//CalculatorBean!steffen.experimental.remote.ejb.RemoteCalculator");
           System.out.println("lookup succeeded, calling remote bean");
           return "result:" + calc.add(1, 1);
      }
      //....
      

      Using the following behaves exactly the same:

             
      ServiceReference sRef = Activator.getBundleContext()
                                    .getServiceReference(InitialContext.class.getName());
      if (sRef != null)
      {
           try{
               InitialContext ctx = (InitialContext)Activator.getBundleContext().getService(sRef);
                ctx.addToEnvironment(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
                System.out.println("doing lookup");
                calc =      
                     (RemoteCalculator)ctx.lookup(
                     "ejb:application-ear-0.0.1-SNAPSHOT/ejb-definition-0.0.1-SNAPSHOT//CalculatorBean!steffen.experimental.remote.ejb.RemoteCalculator");
                System.out.println("lookup succeeded, calling remote bean");
                return "result:" + calc.add(1, 1);
           }     
      //...
      

       

      Both will result in a call to EJBClientContxt.requireCurrent() (in EJBClient) and ultimately end up in the TCCLEJBClientContextSelector which is the locked ContextSelector of the EJBClientContext when the call gets there (no idea when it was set).

       

      My question is:

       

      Why is the ejb client context from the descriptor not used?

       

      I can understand why it is not found in TCCLEJBClientContextSelector as it uses the TCCL as key and that is different at runtime from deploy-time - but looking at the ejbClientContexts-Hashmap of the TCCLEJBClientContextSelectorService,

      the DescriptorBasedEJBClientContext isn't even there to be found!

       

      And worse:

      This works due to the fix of AS7-3830, but only in situations in which the worker thread originates in the OSGi package of the EJB-lookup, where the TCCL will be set to the "HostBundleClassLoader for Module "deployment.steffen.experimental.ejb-remote.accsessor-osgi:0.0.1.SNAPSHOT" from Service Module Loader".

      This fails with a NoClassDefFound-Excpetion for class "RemoteCalculator", when the worker thread originates from a second OSGi bundle that calls the OSGi bundle which makes the EJB-lookup (as the TCCL is set to the HostBundleClassLoader of the thread originating bundle, which - of course - has no import for the interface class of the EJB.

       

      Could somebody please look into this?

       

      Is there a way for an OSGi package to reliably use EJBs via JNDI, independent of the OSGi bundle originating the worker thread?

       

      Thank you!