1 2 Previous Next 15 Replies Latest reply on Jan 22, 2013 10:47 AM by gwwallace

    Remote EJB Call from JMX Method

    gwwallace

      I have an application that deploys ok.

       

      As part of the application's initialization it calls remote EJB methods to get data - this works ok too. (ie all the config and necessary files to make this happen are setup and working)

       

      However, the application also registers JMX beans.

       

      If, at some point after initialization has completed, i invoke a method on one of the JMX beans, which then in turn calls a remote EJB, I get an exception complaining about not being able to find an EJB Context to make the remote call for the current class loader.

       

      How do i set up my application and/or JBoss configuration so that I can invoke a method via JMX that can call out to a remote EJB ?

        • 1. Re: Remote EJB Call from JMX Method
          jaikiran

          Please post the relevant code, configs and exception stacktraces. Also which exact version of AS7 are you using?

          • 2. Re: Remote EJB Call from JMX Method
            cstillwell

            Running: jboss-as-7.2.0.Alpha1-SNAPSHOT

            The server-config is xxi.xml and is attached.

            Stack Trace:

             

            08:33:06,818 DEBUG [org.jboss.as.ejb3.remote.DefaultEJBClientContextSelector] (pool-1-thread-4) Returning default EJB client context org.jboss.ejb.client.EJBClientContext@64948656 since no EJB client context could be found for TCCL ModuleClassLoader for Module "farecompare.atpcore7:main" from local module loader @40bb0f79 (roots: /usr/local/jboss/modules)

            08:33:06,819 WARN  [com.xxi.framework.moduleproxy.JBoss7SynchronousProxy] (pool-1-thread-4) null: java.lang.reflect.InvocationTargetException

                    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_10]

                    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_10]

                    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_10]

                    at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0_10]

                    at com.xxi.framework.moduleproxy.JBoss7SynchronousProxy.doInvoke(JBoss7SynchronousProxy.java:251) [xxi-framework-module-proxy.jar:]

                    at com.xxi.framework.moduleproxy.JBoss7SynchronousProxy.invoke(JBoss7SynchronousProxy.java:211) [xxi-framework-module-proxy.jar:]

                    at $Proxy31.getCities(Unknown Source)   at com.farecompare.atpcore.auxiliarycachemodule.impl.components.ccfs.CCFCacheComponent.getCityGeographyList(CCFCacheComponent.java:426) [farecompare-atpcore-auxiliary-cache-module-impl.jar:]

                    at com.farecompare.atpcore.auxiliarycachemodule.impl.components.ccfs.CCFCacheComponent.reloadCityCache(CCFCacheComponent.java:275) [farecompare-atpcore-auxiliary-cache-module-impl.jar:]

                    at com.farecompare.atpcore.auxiliarycachemodule.impl.components.ccfs.CCFCacheComponent.getCity(CCFCacheComponent.java:98) [farecompare-atpcore-auxiliary-cache-module-impl.jar:]

                    at com.farecompare.atpcore.auxiliarycachemodule.impl.components.ccfs.CCFCacheComponent.getCityFromCityOrAirportCode(CCFCacheComponent.java:105) [farecompare-atpcore-auxiliary-cache-module-impl.jar:]

                    at com.farecompare.atpcore.auxiliarycachemodule.impl.AuxiliaryCacheModule.getCityFromCityOrAirportCode(AuxiliaryCacheModule.java:177) [farecompare-atpcore-auxiliary-cache-module-impl.jar:]

                    at com.farecompare.atpcore.rulemergemodule.impl.RuleMergeFareModule.createContext(RuleMergeFareModule.java:279) [farecompare-atpcore-rule-merge-module-impl.jar:]

                    at com.farecompare.atpcore.rulemergemodule.impl.RuleMergeFareModule.createContext(RuleMergeFareModule.java:263) [farecompare-atpcore-rule-merge-module-impl.jar:]

                    at com.farecompare.atpcore.rulemergemodule.impl.RuleMergeFareModule.getMergedFares(RuleMergeFareModule.java:180) [farecompare-atpcore-rule-merge-module-impl.jar:]

                    at com.farecompare.atpcore.faremixermodule.impl.components.CompileMergedFaresComponent.getMergedFares(CompileMergedFaresComponent.java:277) [farecompare-atpcore-fare-mixer-module-impl.jar:]

                    at com.farecompare.atpcore.faremixermodule.impl.components.CompileMergedFaresTimedComponent.getMergedFares(CompileMergedFaresTimedComponent.java:117) [farecompare-atpcore-fare-mixer-module-impl.jar:]

                    at com.farecompare.atpcore.faremixermodule.impl.components.CompileMergedFaresComponent.compileMergedFares(CompileMergedFaresComponent.java:153) [farecompare-atpcore-fare-mixer-module-impl.jar:]

                    at com.farecompare.atpcore.faremixermodule.impl.components.CompileMergedFaresComponent.compileMergedFaresForMarket(CompileMergedFaresComponent.java:85) [farecompare-atpcore-fare-mixer-module-impl.jar:]

                    at com.farecompare.atpcore.faremixermodule.impl.components.CompileMergedFaresTimedComponent.compileMergedFaresForMarket(CompileMergedFaresTimedComponent.java:31) [farecompare-atpcore-fare-mixer-module-impl.jar:]

                    at com.farecompare.atpcore.faremixermodule.impl.AbstractFareMixerModule.showMergedFares(AbstractFareMixerModule.java:414) [farecompare-atpcore-fare-mixer-module-impl.jar:]

                    at com.farecompare.atpcore.faremixermodule.impl.AbstractFareMixerModule.showMergedFares(AbstractFareMixerModule.java:373) [farecompare-atpcore-fare-mixer-module-impl.jar:]

                    at com.farecompare.atpcore.faremixermodule.impl.AbstractFareMixerModule.showMergedFares_Origin_Dest_RuleCats_Airports(AbstractFareMixerModule.java:264) [farecompare-atpcore-fare-mixer-module-impl.jar:]

                    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_10]

                    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_10]

                    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_10]

                    at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0_10]

                    at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:111) [rt.jar:1.7.0_10]

                    at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:45) [rt.jar:1.7.0_10]

                    at com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(MBeanIntrospector.java:235) [rt.jar:1.7.0_10]

                    at com.sun.jmx.mbeanserver.PerInterface.invoke(PerInterface.java:138) [rt.jar:1.7.0_10]

                    at com.sun.jmx.mbeanserver.MBeanSupport.invoke(MBeanSupport.java:250) [rt.jar:1.7.0_10]

                    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) [rt.jar:1.7.0_10]

                    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:791) [rt.jar:1.7.0_10]

                    at org.jboss.as.jmx.PluggableMBeanServerImpl$TcclMBeanServer.invoke(PluggableMBeanServerImpl.java:527)

                    at org.jboss.as.jmx.PluggableMBeanServerImpl.invoke(PluggableMBeanServerImpl.java:263)

                    at org.jboss.remotingjmx.protocol.v2.ServerProxy$InvokeHandler.handle(ServerProxy.java:911)

                    at org.jboss.remotingjmx.protocol.v2.ServerCommon$MessageReciever$1.run(ServerCommon.java:145)

                    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [rt.jar:1.7.0_10]

                    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [rt.jar:1.7.0_10]

                    at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_10]

            Caused by: java.lang.IllegalStateException: EJBCLIENT000025: No EJB receiver available for handling [appName:data-access-module, moduleName:farecompare-atpcore-data-access-module-ejb, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@6a594e7e

                    at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:675) [jboss-ejb-client-1.0.15.Final.jar:1.0.15.Final]

                    at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:116) [jboss-ejb-client-1.0.15.Final.jar:1.0.15.Final]

                    at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:183) [jboss-ejb-client-1.0.15.Final.jar:1.0.15.Final]

                    at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:177) [jboss-ejb-client-1.0.15.Final.jar:1.0.15.Final]

                    at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:161) [jboss-ejb-client-1.0.15.Final.jar:1.0.15.Final]

                    at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:124) [jboss-ejb-client-1.0.15.Final.jar:1.0.15.Final]

                    at $Proxy54.getCities(Unknown Source)   ... 41 more

             

            08:33:06,828 WARN  [com.xxi.framework.moduleproxy.JBoss7SynchronousProxy] (pool-1-thread-4) EJBCLIENT000025: No EJB receiver available for handling [appName:data-access-module, moduleName:farecompare-atpcore-data-access-module-ejb, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@6a594e7e: java.lang.IllegalStateException: EJBCLIENT000025: No EJB receiver available for handling [appName:data-access-module, moduleName:farecompare-atpcore-data-access-module-ejb, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@6a594e7e

                    at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:675) [jboss-ejb-client-1.0.15.Final.jar:1.0.15.Final]

                    at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:116) [jboss-ejb-client-1.0.15.Final.jar:1.0.15.Final]

                    at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:183) [jboss-ejb-client-1.0.15.Final.jar:1.0.15.Final]

                    at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:177) [jboss-ejb-client-1.0.15.Final.jar:1.0.15.Final]

                    at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:161) [jboss-ejb-client-1.0.15.Final.jar:1.0.15.Final]

                    at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:124) [jboss-ejb-client-1.0.15.Final.jar:1.0.15.Final]

                    at $Proxy54.getCities(Unknown Source)   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_10]

                    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_10]

                    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_10]

                    at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0_10]

                    at com.xxi.framework.moduleproxy.JBoss7SynchronousProxy.doInvoke(JBoss7SynchronousProxy.java:251) [xxi-framework-module-proxy.jar:]

                    at com.xxi.framework.moduleproxy.JBoss7SynchronousProxy.invoke(JBoss7SynchronousProxy.java:211) [xxi-framework-module-proxy.jar:]

                    at $Proxy31.getCities(Unknown Source)   at com.farecompare.atpcore.auxiliarycachemodule.impl.components.ccfs.CCFCacheComponent.getCityGeographyList(CCFCacheComponent.java:426) [farecompare-atpcore-auxiliary-cache-module-impl.jar:]

                    at com.farecompare.atpcore.auxiliarycachemodule.impl.components.ccfs.CCFCacheComponent.reloadCityCache(CCFCacheComponent.java:275) [farecompare-atpcore-auxiliary-cache-module-impl.jar:]

                    at com.farecompare.atpcore.auxiliarycachemodule.impl.components.ccfs.CCFCacheComponent.getCity(CCFCacheComponent.java:98) [farecompare-atpcore-auxiliary-cache-module-impl.jar:]

                    at com.farecompare.atpcore.auxiliarycachemodule.impl.components.ccfs.CCFCacheComponent.getCityFromCityOrAirportCode(CCFCacheComponent.java:105) [farecompare-atpcore-auxiliary-cache-module-impl.jar:]

                    at com.farecompare.atpcore.auxiliarycachemodule.impl.AuxiliaryCacheModule.getCityFromCityOrAirportCode(AuxiliaryCacheModule.java:177) [farecompare-atpcore-auxiliary-cache-module-impl.jar:]

                    at com.farecompare.atpcore.rulemergemodule.impl.RuleMergeFareModule.createContext(RuleMergeFareModule.java:279) [farecompare-atpcore-rule-merge-module-impl.jar:]

                    at com.farecompare.atpcore.rulemergemodule.impl.RuleMergeFareModule.createContext(RuleMergeFareModule.java:263) [farecompare-atpcore-rule-merge-module-impl.jar:]

                    at com.farecompare.atpcore.rulemergemodule.impl.RuleMergeFareModule.getMergedFares(RuleMergeFareModule.java:180) [farecompare-atpcore-rule-merge-module-impl.jar:]

                    at com.farecompare.atpcore.faremixermodule.impl.components.CompileMergedFaresComponent.getMergedFares(CompileMergedFaresComponent.java:277) [farecompare-atpcore-fare-mixer-module-impl.jar:]

                    at com.farecompare.atpcore.faremixermodule.impl.components.CompileMergedFaresTimedComponent.getMergedFares(CompileMergedFaresTimedComponent.java:117) [farecompare-atpcore-fare-mixer-module-impl.jar:]

                    at com.farecompare.atpcore.faremixermodule.impl.components.CompileMergedFaresComponent.compileMergedFares(CompileMergedFaresComponent.java:153) [farecompare-atpcore-fare-mixer-module-impl.jar:]

                    at com.farecompare.atpcore.faremixermodule.impl.components.CompileMergedFaresComponent.compileMergedFaresForMarket(CompileMergedFaresComponent.java:85) [farecompare-atpcore-fare-mixer-module-impl.jar:]

                    at com.farecompare.atpcore.faremixermodule.impl.components.CompileMergedFaresTimedComponent.compileMergedFaresForMarket(CompileMergedFaresTimedComponent.java:31) [farecompare-atpcore-fare-mixer-module-impl.jar:]

                    at com.farecompare.atpcore.faremixermodule.impl.AbstractFareMixerModule.showMergedFares(AbstractFareMixerModule.java:414) [farecompare-atpcore-fare-mixer-module-impl.jar:]

                    at com.farecompare.atpcore.faremixermodule.impl.AbstractFareMixerModule.showMergedFares(AbstractFareMixerModule.java:373) [farecompare-atpcore-fare-mixer-module-impl.jar:]

                    at com.farecompare.atpcore.faremixermodule.impl.AbstractFareMixerModule.showMergedFares_Origin_Dest_RuleCats_Airports(AbstractFareMixerModule.java:264) [farecompare-atpcore-fare-mixer-module-impl.jar:]

                    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_10]

                    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_10]

                    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_10]

                    at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0_10]

                    at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:111) [rt.jar:1.7.0_10]

                    at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:45) [rt.jar:1.7.0_10]

                    at com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(MBeanIntrospector.java:235) [rt.jar:1.7.0_10]

                    at com.sun.jmx.mbeanserver.PerInterface.invoke(PerInterface.java:138) [rt.jar:1.7.0_10]

                    at com.sun.jmx.mbeanserver.MBeanSupport.invoke(MBeanSupport.java:250) [rt.jar:1.7.0_10]

                    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) [rt.jar:1.7.0_10]

                    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:791) [rt.jar:1.7.0_10]

                    at org.jboss.as.jmx.PluggableMBeanServerImpl$TcclMBeanServer.invoke(PluggableMBeanServerImpl.java:527)

                    at org.jboss.as.jmx.PluggableMBeanServerImpl.invoke(PluggableMBeanServerImpl.java:263)

                    at org.jboss.remotingjmx.protocol.v2.ServerProxy$InvokeHandler.handle(ServerProxy.java:911)

                    at org.jboss.remotingjmx.protocol.v2.ServerCommon$MessageReciever$1.run(ServerCommon.java:145)

                    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [rt.jar:1.7.0_10]

                    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [rt.jar:1.7.0_10]

                    at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_10]

            • 3. Re: Remote EJB Call from JMX Method
              jaikiran

              Are the EJBs deployed on the same server as this deployment which is failing? If yes, what does the server log look like w.r.t the JNDI names? Does this failing JMX application contain a jboss-ejb-client.xml?

              • 4. Re: Remote EJB Call from JMX Method
                cstillwell

                We have data access components and EJBs deployed on server1.  We have application components deployed on server2.  The component jars are deployed within a global module.  The components get instatiated and registered via a service annotated with @Startup, @Singleton which is deployed in an ear that does contain a jboss-ejb-client.xml.  During the initialization of the application components remote calls are successfully made from server2 to server1.  After initialization I can access the components on server2 via a JMX connection using jconsole. However, if I attempt any operation that needs to make remote calls to server1 it fails.  Further, I can deploy an ear on server2 that contains an EJB that looks up a component on server2 via jndi and delegates all of its operations to that component.  If from a remote client I invoke an operation on the EJB on server2, which just delegates to a component on server2, which calls a remote EJB on server1 it works fine.  So in summary remote client->EJB on server2->component on server2->EJB on server1 works, but JMX->component on server2->EJB on server1 fails. 

                • 5. Re: Remote EJB Call from JMX Method
                  jaikiran

                  Is farecompare.atpcore7 a jar? What does its packaging look like? Post the output of:

                   

                  jar -tf farecompare.atpcore7.jar

                   

                  (replace .jar with .war if it's a war)

                   

                  It should contain the jboss-ejb-client.xml.

                  • 6. Re: Remote EJB Call from JMX Method
                    gwwallace

                    farecompare.atpcore7 is a global module that consists of about 30-40 jar files.

                     

                    I guess the problem here is understanding how the class loader affects the EJB context being used.

                     

                    The @Startup EJB that instantiates all the classes (from the global modules), is in an ear with the jboss-ejb-client.xml - we'd assumed that any access subsequently to those classes would fall under the control of the EJB Context that was created for that app.

                     

                    For example, our service does the following:

                     

                    1. During deployment of the ear - @Startup EJB is instantiated

                    2. @Startup EJB reads configuration XML file

                    3. Each entry in the configuration XML file describes a class that gets instantiated, put into JNDI and exposed as a MBean

                    4. For each class instantiated,  initialization takes place.

                    5. As part of the initialization process, the class can lookup and call out to remote EJBs.

                    6. Deployment of ear completes.

                    7. Deployment of EJB ear starts

                    8. EJB initialization occurs and a JNDI lookup is done to find the appropriate instantiated class from before.

                    9. End deployment EJB

                    10. A remote client connects to the deployed EJB, and makes a call. This is turn makes another call out to a remote EJB and because the original ear has a jboss-ejb-client.xml this works.

                    11. JConsole is connected to the server. A method is called on one of the instantiated classes, but this time the remote EJB call fails.

                     

                    So the problem we are having is that we don't understand how the EJB call can use the classes instantiated by the @Startup EJB and find the correct EJB Context, but a JMX method call using the same classes cant find the correct EJB context.

                    • 7. Re: Remote EJB Call from JMX Method
                      jaikiran

                      When you invoke via JConsole, the TCCL gets set to the classloader of the MBean. Based on what I see in the stacktrace and the logs, your MBean appears to have been packaged in the farecompare.atpcore7 global module which then acts as a client for the EJB invocation. As a result, the EJB invocation looks for the jboss-ejb-client.xml in the farecompare.atpcore7 module.

                      • 8. Re: Remote EJB Call from JMX Method
                        gwwallace

                        Ok - but isnt the class loader of the MBean the class loader that is active when the initial ear is deployed to create them ? I guess thats the bit i dont understand - there's a class loader for the ear, but does that class loader load the global modules as required  ? If not, then how does a call into an EJB then work when it uses the classes from farecompare.atpcore7 that were loaded at initial deployment time ? Shouldnt that fail for the same reason as the JMX call ?

                        • 9. Re: Remote EJB Call from JMX Method
                          cstillwell

                          How do we add a jboss-ejb-client.xml file to the farecompare.atpcore7 module?  I have tried adding one to the ~/jboss/modules/farecompare/atpcore7/main directory.  I've tried creating a jboss/modules/farecompare/atpcore7/main/META-INF directory and adding it there along with adding a <resource-root path="META-INF"/> element in the module.xml. Neither work.

                          • 10. Re: Remote EJB Call from JMX Method
                            gwwallace

                            Any ideas on a solution for this ? We have a ton of classes that expose themselves as MBeans when instantiated by a 'loader' ear, so it would be a huge pain to try and extract all them and build into the ear.

                            • 11. Re: Remote EJB Call from JMX Method
                              jaikiran

                              It's much more than just placing the jboss-ejb-client.xml in the "module". The parsing of jboss-ejb-client.xml and other similar deployment descriptors is only supported within deployments. A (JBoss) "module" is not a deployment. So placing a jboss-ejb-client.xml in there is of no use.

                              Any ideas on a solution for this ? We have a ton of classes that expose themselves as MBeans when instantiated by a 'loader' ear, so it would be a huge pain to try and extract all them and build into the ear.

                              So you have (JBoss) module which accesses certain deployment resources (like classes/interfaces) within the classes of the module? How do you do that currently? Typically it's the other way around.

                              • 12. Re: Remote EJB Call from JMX Method
                                gwwallace

                                Our setup is coming from JBoss 4 - which we've used for the last 7 or 8 years - so a lot of this is dealing with legacy decisions and implementation we made a long time ago.

                                 

                                The idea of placing our core functionality in global modules was to get around not having a webdav enabled class loader like in JBoss 4.

                                 

                                For each server type, we configure which parts of our core functionality are to be instantiated by an EJB which reads a XML configuration file (we call it our ModuleLoaderService) at startup.

                                This not only instantiates the appropriate core classes, puts them into JNDI and registers them with JMX. It also has the ability to create dynamic proxies that are basically a wrapper around a remote JNDI lookup to other EJB server(s).

                                 

                                Each core class then has the ability to look into local JNDI to extract either local functionality or remote functionality without needing to know where it exists. The ear that the ModuleLoaderService is packaged in has the necessary jboss-ejb-client.xml to enable the remote EJB.

                                 

                                Now, if i want to expose some of the core functionality as an EJB, I simply create an ear with the appropriate packaging and deploy it.

                                When a client app makes a call, the EJB itself does a local JNDI lookup to find the appropriate core class and delegates the method call.

                                If, at this point, the core class wants to call out to another EJB server, it will first get the dynamic proxy from a local JNDI lookup and make the call. This works without having to add the jboss-ejb-client.xml to the new ear - ie it uses the EJB Context that was created by having the jboss-ejb-client.xml in the ModuleLoaderService ear.

                                 

                                However, if the core class is entered via JMX, then the affinity to the EJB Context from the MOduleLoaderService is lost and its this part that i dont understand. If the core class is instantiated by the deployment of the ModuleLoaderService ear, why doesnt it always have affinity to the EJB Context for that ear ? Especially as this works when the core class is 'entered' via an EJB call.

                                • 13. Re: Remote EJB Call from JMX Method
                                  jaikiran

                                  Graeme Wallace wrote:

                                   

                                   

                                  However, if the core class is entered via JMX, then the affinity to the EJB Context from the MOduleLoaderService is lost and its this part that i dont understand. If the core class is instantiated by the deployment of the ModuleLoaderService ear, why doesnt it always have affinity to the EJB Context for that ear ? Especially as this works when the core class is 'entered' via an EJB call.

                                  The point you are missing is the classloaders that are used for finding the right EJBClientContext. When the control enters directly into the JMX core class packaged in the module, via JConsole, the thread context classloader is set to the module, which effectively means that, that classloader is used to find the EJBClientContext. Now that classloader doesn't have visibility to your deployment .ear and hence won't find the context.

                                   

                                  Now when you are entering a core class packaged in a module, via some other *deployed component* then the thread context classloader is set to the deployment from which the invocation is being carried out. So in that case it has the visibility to the jboss-ejb-client.xml and hence the appropriate EJBClientContext.

                                   

                                  My real question hasn't yet been answered though - you said that the core module does the EJB invocations by looking up the EJBs. So how and where does it find the EJB interfaces? Are those packaged within the core module?

                                  • 14. Re: Remote EJB Call from JMX Method
                                    cstillwell

                                    Yes, the EJB interfaces are packaged as part of the module.  In the below example the FaresAccessModuleAPI is packaged in the farecompare.atpcore7 module.  The only thing packaged in the deployment ear is the jar that contains the DomesticFaresAccessModuleSessionBean class.  The _delegate is loaded from local JNDI and all the implementation methods in the session bean just delegate to it. 

                                     

                                     

                                    /**

                                    * Stateless Session Bean EJB facade for FaresAccessModule

                                    */

                                    @Stateless

                                    @Remote(FaresAccessModuleAPI.class)

                                    @TransactionManagement( TransactionManagementType.BEAN)

                                    public class DomesticFaresAccessModuleSessionBean implements FaresAccessModuleAPI {

                                     

                                        private static final long SLEEP_TIME_WAITING_FOR_DELEGATE = 1000L;

                                        private static final long MAXIMUM_WAIT_FOR_DELEGATE = 2L * 60L * 1000L; //two minutes

                                     

                                        @Resource(name="module.name")

                                        private String _moduleName;

                                     

                                        private FaresAccessModuleAPI _delegate;

                                     

                                        protected Log getLog() {

                                            return LogFactory.getLog( getClass() );

                                        }

                                     

                                        @PostConstruct

                                        public void init() {

                                            try {

                                                getLog().info( "init lookup " + _moduleName );

                                                _delegate = (FaresAccessModuleAPI) ModuleLookupService.getInstance().lookupModule( _moduleName );

                                            } catch ( ModuleLookupException e ) {

                                                e.printStackTrace();

                                            }

                                        }

                                    1 2 Previous Next