TCCL used EJBNamingContext is wrong when callstack passes through multiple OSGi modules

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

TCCL used EJBNamingContext is wrong when callstack passes through multiple OSGi modules

Wollscheid. Steffen

Hi all,

 

we face the following problem:

 

We would like to be able to trigger a chain of events, say by JMX-Bean in on OSGi bundle [A].

[A] then calls up an OSGi Service/Class located in bundle [B] using an interface exported by [B].

Now [B] tries to make a remote EJB lookup into an ear [C] on an interface it imported from another OSGi Bundle [D].

 

This fails with the following stacktrace:

[Server:server-one] 15:46:32,245 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110) javax.naming.NamingException: Could not load ejb proxy class steffen.experimental.remote.ejb.RemoteCalculator [Root exception is java.lang.ClassNotFoundException: steffen.experimental.remote.ejb.RemoteCalculator from [Module "deployment.steffen.experimental.ejb-remote.twice-removed:0.0.1.SNAPSHOT" from Service Module Loader]]

[Server:server-one] 15:46:32,245 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at org.jboss.ejb.client.naming.ejb.EjbNamingContext.createEjbProxy(EjbNamingContext.java:108)

[Server:server-one] 15:46:32,246 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at org.jboss.ejb.client.naming.ejb.EjbNamingContext.lookup(EjbNamingContext.java:96)

[Server:server-one] 15:46:32,246 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at org.jboss.ejb.client.naming.ejb.EjbNamingContext.lookup(EjbNamingContext.java:76)

[Server:server-one] 15:46:32,246 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at org.jboss.as.naming.InitialContext.lookup(InitialContext.java:100)

[Server:server-one] 15:46:32,246 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:213)

[Server:server-one] 15:46:32,246 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)

[Server:server-one] 15:46:32,246 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at steffen.experimental.client.jmx.service.LookupImpl.internal_InitialContextService(LookupImpl.java:63)

[Server:server-one] 15:46:32,247 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at steffen.experimental.client.jmx.service.TriggerLookup.doAddition_InitialContextService(TriggerLookup.java:85)

[Server:server-one] 15:46:32,247 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at steffen.experimental.indirect.jmx.ServiceCallerWrapper.doAddition_InitialContextService(ServiceCallerWrapper.java:30)

[Server:server-one] 15:46:32,247 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

 

Where “twice-removed” is [A] and the class TriggerLookup does reside in [B].

 

(We have aries.jndi running in our jboss, but the behavior described here occurs also without aries.jndi – in fact we had hoped that would solve our problems)

 

It is important to note, that the same code in [B] works alright, when the initiating JMX Bean resides in [B] instead of [A], because in this case the TCCL is bundle classloader of bundle [B], whereas in the other case it is the bundle classloader of [A] which of course has not knowledge of the interface class.

 

Furthermore it is important to note that this behavior occurs even though the flow of control from [A] to [B] is done using:

 

    private TriggerLookupMBean getService(){

        ServiceReference sRef = TwiceRemovedActivator.getBundleContext().getServiceReference(TriggerLookupMBean.class.getName());

        if( sRef != null ){

            return (TriggerLookupMBean) TwiceRemovedActivator.getBundleContext().getService(sRef);

        } else {

            throw new IllegalStateException("Service TriggerLookupMBean was not found!");

        }

    }

 

    public String doAddition_InitialContextService()

    {

        return getService().doAddition_InitialContextService();

    }

 

So that the OSGi framework would have a chance to change the TCCL using an interceptor hooked into the service which is returned by getService.

But from what I see simply an instance of the implementation class from bundle [B] is returned.

 

Am I doing something wrong here? Having aries.jndi installed, I can do a successful JNDI lookup for an OSGi Service regardless of the Bundle initiating the flow of control, while the same lookup, when done with a “ejb:” prefix fails.

 

This works:

        AnOSGiService otherSvc = null;

        ServiceReference sRef = Activator.getBundleContext()

                        .getServiceReference(JNDIContextManager.class.getName());

        if (sRef != null)

        {

            JNDIContextManager contextMgr = (JNDIContextManager) Activator.getBundleContext().getService(sRef);

 

            try

            {

                Properties props = new Properties();

                props.put("osgi.service.jndi.bundleContext", Activator.getBundleContext());

                Context ctx = contextMgr.newInitialContext(props);

                System.out.println("doing JNDI lookup");

                otherSvc = (AnOSGiService) ctx.lookup("osgi:service/" + AnOSGiService.class.getName());

                System.out.println("lookup succeeded, calling service");

                return "result:" + otherSvc.foo();

            }

 

This fails:

 

        RemoteCalculator calc = null;

        ServiceReference sRef = Activator.getBundleContext()

                        .getServiceReference(JNDIContextManager.class.getName());

        if (sRef != null)

        {

            JNDIContextManager contextMgr = (JNDIContextManager) Activator.getBundleContext().getService(sRef);

 

            try

            {

                Properties props = new Properties();

                props.put("osgi.service.jndi.bundleContext", Activator.getBundleContext());

                props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");

                Context ctx = contextMgr.newInitialContext(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);

            }

 

 

As I mentioned before when called from a JMX-Bean in the same bundle both work!

What am I missing?

 

Our current workaround is an aspect that changes the TCCL in exported public methods if required – but I believe this should not be necessary.

 

Thanks for your patience reading this!

Sincerely

 

Steffen

 

 

 

 

 

 

 

 

 




...

     


SEEBURGER AG   Vorstand/Seeburger Executive Board:
Sitz der Gesellschaft/Registered Office:   Bernd Seeburger, Axel Haas, Michael Kleeberg
Edisonstr. 1  
D-75015 Bretten Vorsitzender des Aufsichtsrats/Chairperson of the Seeburger Supervisory Board:
Tel.: 07252 / 96 - 0 Dr. Franz Scherer
Fax: 07252 / 96 - 2222
Internet: http://www.seeburger.de Registergericht/Commercial Register:
e-mail: [hidden email] HRB 240708 Mannheim


Dieses E-Mail ist nur für den Empfänger bestimmt, an den es gerichtet ist und kann vertrauliches bzw. unter das Berufsgeheimnis fallendes Material enthalten. Jegliche darin enthaltene Ansicht oder Meinungsäußerung ist die des Autors und stellt nicht notwendigerweise die Ansicht oder Meinung der SEEBURGER AG dar. Sind Sie nicht der Empfänger, so haben Sie diese E-Mail irrtümlich erhalten und jegliche Verwendung, Veröffentlichung, Weiterleitung, Abschrift oder jeglicher Druck dieser E-Mail ist strengstens untersagt. Weder die SEEBURGER AG noch der Absender ( Wollscheid. Steffen ) übernehmen die Haftung für Viren; es obliegt Ihrer Verantwortung, die E-Mail und deren Anhänge auf Viren zu prüfen.

The present email addresses only the addressee which it targets and may contain confidential material that may be protected by the professional secret. The opinions reflected herein are not necessarily the one of the SEEBURGER AG. If you are not the addressee, you have accidentally got this email and are not enabled to use, publish, forward, copy or print it in any way. Neither SEEBURGER AG , nor the sender (Wollscheid. Steffen) are liable for viruses, being your own responsibility to check this email and its attachments for this purpose.


_______________________________________________
jboss-as7-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/jboss-as7-dev
Reply | Threaded
Open this post in threaded view
|

Re: TCCL used EJBNamingContext is wrong when callstack passes through multiple OSGi modules

Thomas Diesler
Please take this to the jbosgi user forum

-thomas

On 03/09/2012 05:19 PM, Wollscheid. Steffen wrote:

Hi all,

 

we face the following problem:

 

We would like to be able to trigger a chain of events, say by JMX-Bean in on OSGi bundle [A].

[A] then calls up an OSGi Service/Class located in bundle [B] using an interface exported by [B].

Now [B] tries to make a remote EJB lookup into an ear [C] on an interface it imported from another OSGi Bundle [D].

 

This fails with the following stacktrace:

[Server:server-one] 15:46:32,245 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110) javax.naming.NamingException: Could not load ejb proxy class steffen.experimental.remote.ejb.RemoteCalculator [Root exception is java.lang.ClassNotFoundException: steffen.experimental.remote.ejb.RemoteCalculator from [Module "deployment.steffen.experimental.ejb-remote.twice-removed:0.0.1.SNAPSHOT" from Service Module Loader]]

[Server:server-one] 15:46:32,245 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at org.jboss.ejb.client.naming.ejb.EjbNamingContext.createEjbProxy(EjbNamingContext.java:108)

[Server:server-one] 15:46:32,246 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at org.jboss.ejb.client.naming.ejb.EjbNamingContext.lookup(EjbNamingContext.java:96)

[Server:server-one] 15:46:32,246 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at org.jboss.ejb.client.naming.ejb.EjbNamingContext.lookup(EjbNamingContext.java:76)

[Server:server-one] 15:46:32,246 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at org.jboss.as.naming.InitialContext.lookup(InitialContext.java:100)

[Server:server-one] 15:46:32,246 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:213)

[Server:server-one] 15:46:32,246 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)

[Server:server-one] 15:46:32,246 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at steffen.experimental.client.jmx.service.LookupImpl.internal_InitialContextService(LookupImpl.java:63)

[Server:server-one] 15:46:32,247 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at steffen.experimental.client.jmx.service.TriggerLookup.doAddition_InitialContextService(TriggerLookup.java:85)

[Server:server-one] 15:46:32,247 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at steffen.experimental.indirect.jmx.ServiceCallerWrapper.doAddition_InitialContextService(ServiceCallerWrapper.java:30)

[Server:server-one] 15:46:32,247 ERROR [stderr] (RMI TCP Connection(4)-10.0.103.110)    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

 

Where “twice-removed” is [A] and the class TriggerLookup does reside in [B].

 

(We have aries.jndi running in our jboss, but the behavior described here occurs also without aries.jndi – in fact we had hoped that would solve our problems)

 

It is important to note, that the same code in [B] works alright, when the initiating JMX Bean resides in [B] instead of [A], because in this case the TCCL is bundle classloader of bundle [B], whereas in the other case it is the bundle classloader of [A] which of course has not knowledge of the interface class.

 

Furthermore it is important to note that this behavior occurs even though the flow of control from [A] to [B] is done using:

 

    private TriggerLookupMBean getService(){

        ServiceReference sRef = TwiceRemovedActivator.getBundleContext().getServiceReference(TriggerLookupMBean.class.getName());

        if( sRef != null ){

            return (TriggerLookupMBean) TwiceRemovedActivator.getBundleContext().getService(sRef);

        } else {

            throw new IllegalStateException("Service TriggerLookupMBean was not found!");

        }

    }

 

    public String doAddition_InitialContextService()

    {

        return getService().doAddition_InitialContextService();

    }

 

So that the OSGi framework would have a chance to change the TCCL using an interceptor hooked into the service which is returned by getService.

But from what I see simply an instance of the implementation class from bundle [B] is returned.

 

Am I doing something wrong here? Having aries.jndi installed, I can do a successful JNDI lookup for an OSGi Service regardless of the Bundle initiating the flow of control, while the same lookup, when done with a “ejb:” prefix fails.

 

This works:

        AnOSGiService otherSvc = null;

        ServiceReference sRef = Activator.getBundleContext()

                        .getServiceReference(JNDIContextManager.class.getName());

        if (sRef != null)

        {

            JNDIContextManager contextMgr = (JNDIContextManager) Activator.getBundleContext().getService(sRef);

 

            try

            {

                Properties props = new Properties();

                props.put("osgi.service.jndi.bundleContext", Activator.getBundleContext());

                Context ctx = contextMgr.newInitialContext(props);

                System.out.println("doing JNDI lookup");

                otherSvc = (AnOSGiService) ctx.lookup("osgi:service/" + AnOSGiService.class.getName());

                System.out.println("lookup succeeded, calling service");

                return "result:" + otherSvc.foo();

            }

 

This fails:

 

        RemoteCalculator calc = null;

        ServiceReference sRef = Activator.getBundleContext()

                        .getServiceReference(JNDIContextManager.class.getName());

        if (sRef != null)

        {

            JNDIContextManager contextMgr = (JNDIContextManager) Activator.getBundleContext().getService(sRef);

 

            try

            {

                Properties props = new Properties();

                props.put("osgi.service.jndi.bundleContext", Activator.getBundleContext());

                props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");

                Context ctx = contextMgr.newInitialContext(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);

            }

 

 

As I mentioned before when called from a JMX-Bean in the same bundle both work!

What am I missing?

 

Our current workaround is an aspect that changes the TCCL in exported public methods if required – but I believe this should not be necessary.

 

Thanks for your patience reading this!

Sincerely

 

Steffen

 

 

 

 

 

 

 

 

 




...

     


SEEBURGER AG   Vorstand/Seeburger Executive Board:
Sitz der Gesellschaft/Registered Office:   Bernd Seeburger, Axel Haas, Michael Kleeberg
Edisonstr. 1  
D-75015 Bretten
Vorsitzender des Aufsichtsrats/Chairperson of the Seeburger Supervisory Board:
Tel.: 07252 / 96 - 0
Dr. Franz Scherer
Fax: 07252 / 96 - 2222

Internet: http://www.seeburger.de
Registergericht/Commercial Register:
e-mail: [hidden email]
HRB 240708 Mannheim


Dieses E-Mail ist nur für den Empfänger bestimmt, an den es gerichtet ist und kann vertrauliches bzw. unter das Berufsgeheimnis fallendes Material enthalten. Jegliche darin enthaltene Ansicht oder Meinungsäußerung ist die des Autors und stellt nicht notwendigerweise die Ansicht oder Meinung der SEEBURGER AG dar. Sind Sie nicht der Empfänger, so haben Sie diese E-Mail irrtümlich erhalten und jegliche Verwendung, Veröffentlichung, Weiterleitung, Abschrift oder jeglicher Druck dieser E-Mail ist strengstens untersagt. Weder die SEEBURGER AG noch der Absender ( Wollscheid. Steffen ) übernehmen die Haftung für Viren; es obliegt Ihrer Verantwortung, die E-Mail und deren Anhänge auf Viren zu prüfen.

The present email addresses only the addressee which it targets and may contain confidential material that may be protected by the professional secret. The opinions reflected herein are not necessarily the one of the SEEBURGER AG. If you are not the addressee, you have accidentally got this email and are not enabled to use, publish, forward, copy or print it in any way. Neither SEEBURGER AG , nor the sender (Wollscheid. Steffen) are liable for viruses, being your own responsibility to check this email and its attachments for this purpose.



_______________________________________________
jboss-as7-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/jboss-as7-dev

-- 
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Thomas Diesler
JBoss OSGi Lead
JBoss, a division of Red Hat
xxxxxxxxxxxxxxxxxxxxxxxxxxxx 

_______________________________________________
jboss-as7-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/jboss-as7-dev