[jboss-as7-dev] TCCL used EJBNamingContext is wrong when callstack passes through multiple OSGi modules
Wollscheid. Steffen
s.wollscheid at seeburger.de
Fri Mar 9 11:19:09 EST 2012
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: info at seeburger.de 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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/jboss-as7-dev/attachments/20120309/01ba128c/attachment-0001.html
More information about the jboss-as7-dev
mailing list