[jboss-dev-forums] [Design of EJB 3.0] - Quartz MDB integration and classloader issues
jaikiran
do-not-reply at jboss.com
Fri Jul 24 19:42:11 EDT 2009
There have been more than a couple of users now, having trouble with getting the Quartz integration with MDB running. Here are the 2 instances, for example:
http://www.jboss.org/index.html?module=bb&op=viewtopic&t=158926
http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4229808
The real issue is classloading where the quartz thread triggers a job. The QuartzJob which does this (and is triggered through quartz-ra.rar) has the base classloader which does not have access to user deployment classloader. So if you have your MDB packaged in a deployment with its own classloader (which is practical), then the QuartzJob will not have access to the EJBs in the user deployment leading to exceptions like:
| javax.ejb.EJBTransactionRolledbackException: Unable to inject jndi dependency: env/org.jboss.tutorial.quartz.bean.AnnotatedQuartzMDBBean/calc into property org.jboss.tutorial.quartz.bean.AnnotatedQuartzMDBBean.calc: org.jboss.tutorial.quartz.bean.Calculator from BaseClassLoader at 1f172aa{VFSClassLoaderPolicy at 9f3364{name=vfszip:/home/jpai/jboss-5.1.0.GA/server/default/deploy/quartz-ra.rar/ domain=ClassLoaderDomain at 1f5eb7f{name=DefaultDomain parentPolicy=BEFORE parent=org.jboss.bootstrap.NoAnnotationURLClassLoader at 1431340} roots=[MemoryContextHandler at 31918682[path= context=vfsmemory://3j001-a542up-fxj4w94o-1-fxj4x19a-21 real=vfsmemory://3j001-a542up-fxj4w94o-1-fxj4x19a-21], DelegatingHandler at 22593168[path=quartz-ra.rar context=file:/home/jpai/jboss-5.1.0.GA/server/default/deploy/ real=file:/home/jpai/jboss-5.1.0.GA/server/default/deploy/quartz-ra.rar], DelegatingHandler at 21430906[path=quartz-ra.rar/quartz-ra.jar context=file:/home/jpai/jboss-5.1.0.GA/server/default/deploy/ real=file:/home/jpai/jboss-5.1.0.GA/server/default/deploy/quartz-ra.rar/quartz-ra.jar]] delegates=null exported=[META-INF, org.jboss.resource.adapter.quartz.inflow] <IMPORT-ALL>NON_EMPTY}}
| at org.jboss.ejb3.tx.Ejb3TxPolicy.handleInCallerTx(Ejb3TxPolicy.java:115)
| at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:130)
| at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:194)
| at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
| at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
| at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
| at org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:80)
| at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
| at org.jboss.ejb3.BlockContainerShutdownInterceptor.invoke(BlockContainerShutdownInterceptor.java:67)
| at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
| at org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67)
| at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
| at org.jboss.ejb3.mdb.MessagingContainer.localInvoke(MessagingContainer.java:282)
| at org.jboss.ejb3.mdb.inflow.MessageInflowLocalProxy.delivery(MessageInflowLocalProxy.java:270)
| at org.jboss.ejb3.mdb.inflow.MessageInflowLocalProxy.invoke(MessageInflowLocalProxy.java:140)
| at $Proxy136.execute(Unknown Source)
| at org.jboss.resource.adapter.quartz.inflow.QuartzJob.execute(QuartzJob.java:57)
| at org.quartz.core.JobRunShell.run(JobRunShell.java:203)
| at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520)
| Caused by: java.lang.RuntimeException: Unable to inject jndi dependency: env/org.jboss.tutorial.quartz.bean.AnnotatedQuartzMDBBean/calc into property org.jboss.tutorial.quartz.bean.AnnotatedQuartzMDBBean.calc: org.jboss.tutorial.quartz.bean.Calculator from BaseClassLoader at 1f172aa{VFSClassLoaderPolicy at 9f3364{name=vfszip:/home/jpai/jboss-5.1.0.GA/server/default/deploy/quartz-ra.rar/ domain=ClassLoaderDomain at 1f5eb7f{name=DefaultDomain parentPolicy=BEFORE parent=org.jboss.bootstrap.NoAnnotationURLClassLoader at 1431340} roots=[MemoryContextHandler at 31918682[path= context=vfsmemory://3j001-a542up-fxj4w94o-1-fxj4x19a-21 real=vfsmemory://3j001-a542up-fxj4w94o-1-fxj4x19a-21], DelegatingHandler at 22593168[path=quartz-ra.rar context=file:/home/jpai/jboss-5.1.0.GA/server/default/deploy/ real=file:/home/jpai/jboss-5.1.0.GA/server/default/deploy/quartz-ra.rar], DelegatingHandler at 21430906[path=quartz-ra.rar/quartz-ra.jar context=file:/home/jpai/jboss-5.1.0.GA/server/default/deploy/ real=file:/home/jpai/jboss-5.1.0.GA/server/default/deploy/quartz-ra.rar/quartz-ra.jar]] delegates=null exported=[META-INF, org.jboss.resource.adapter.quartz.inflow] <IMPORT-ALL>NON_EMPTY}}
| at org.jboss.injection.JndiPropertyInjector.lookup(JndiPropertyInjector.java:82)
| at org.jboss.injection.JndiPropertyInjector.inject(JndiPropertyInjector.java:99)
| at org.jboss.injection.JndiPropertyInjector.inject(JndiPropertyInjector.java:89)
| at org.jboss.injection.JndiPropertyInjector.inject(JndiPropertyInjector.java:61)
| at org.jboss.ejb3.injection.InjectionInvocation.invokeTarget(InjectionInvocation.java:89)
| at org.jboss.ejb3.injection.InjectionInvocation.invokeNext(InjectionInvocation.java:83)
| at org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67)
| at org.jboss.ejb3.injection.InjectionInvocation.invokeNext(InjectionInvocation.java:74)
| at org.jboss.ejb3.EJBContainer.injectBeanContext(EJBContainer.java:1097)
| at org.jboss.ejb3.pool.AbstractPool.create(AbstractPool.java:83)
| at org.jboss.ejb3.pool.AbstractPool.create(AbstractPool.java:73)
| at org.jboss.ejb3.pool.StrictMaxPool.get(StrictMaxPool.java:146)
| at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:58)
| at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
| at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126)
| ... 17 more
| Caused by: javax.naming.NamingException: Could not dereference object [Root exception is javax.naming.NamingException: Could not dereference object [Root exception is java.lang.RuntimeException: Can not find interface declared by Proxy in our CL + BaseClassLoader at 1f172aa{vfszip:/home/jpai/jboss-5.1.0.GA/server/default/deploy/quartz-ra.rar/}]]
| at org.jnp.interfaces.NamingContext.resolveLink(NamingContext.java:1352)
| at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:817)
| at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:686)
| at org.jboss.ejb3.JndiUtil.lookup(JndiUtil.java:44)
| at org.jboss.injection.JndiPropertyInjector.lookup(JndiPropertyInjector.java:75)
| ... 31 more
| Caused by: javax.naming.NamingException: Could not dereference object [Root exception is java.lang.RuntimeException: Can not find interface declared by Proxy in our CL + BaseClassLoader at 1f172aa{vfszip:/home/jpai/jboss-5.1.0.GA/server/default/deploy/quartz-ra.rar/}]
| at org.jnp.interfaces.NamingContext.getObjectInstanceWrapFailure(NamingContext.java:1504)
| at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:822)
| at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:686)
| at javax.naming.InitialContext.lookup(InitialContext.java:351)
| at org.jnp.interfaces.NamingContext.resolveLink(NamingContext.java:1346)
| ... 35 more
| Caused by: java.lang.RuntimeException: Can not find interface declared by Proxy in our CL + BaseClassLoader at 1f172aa{vfszip:/home/jpai/jboss-5.1.0.GA/server/default/deploy/quartz-ra.rar/}
| at org.jboss.ejb3.proxy.impl.objectfactory.ProxyObjectFactory.redefineProxyInTcl(ProxyObjectFactory.java:343)
| at org.jboss.ejb3.proxy.impl.objectfactory.session.SessionProxyObjectFactory.createProxy(SessionProxyObjectFactory.java:134)
| at org.jboss.ejb3.proxy.impl.objectfactory.session.stateless.StatelessSessionProxyObjectFactory.getProxy(StatelessSessionProxyObjectFactory.java:79)
| at org.jboss.ejb3.proxy.impl.objectfactory.ProxyObjectFactory.getObjectInstance(ProxyObjectFactory.java:158)
| at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:304)
| at org.jnp.interfaces.NamingContext.getObjectInstance(NamingContext.java:1479)
| at org.jnp.interfaces.NamingContext.getObjectInstanceWrapFailure(NamingContext.java:1496)
| ... 39 more
|
Looking at the code, i think the right way to fix this is to change the org.jboss.ejb3.mdb.inflow.MessageInflowLocalProxy.delivery to deliver the message as part of the container's classloader:
| Index: src/main/java/org/jboss/ejb3/mdb/inflow/MessageInflowLocalProxy.java
| ===================================================================
| --- src/main/java/org/jboss/ejb3/mdb/inflow/MessageInflowLocalProxy.java (revision 91150)
| +++ src/main/java/org/jboss/ejb3/mdb/inflow/MessageInflowLocalProxy.java (working copy)
| - return delivery(proxy, container, method, args);
| + {
| + ClassLoader earlierClassLoader = Thread.currentThread().getContextClassLoader();
| + try
| + {
| + // Deliver the message through the container's classloader
| + Thread.currentThread().setContextClassLoader(container.getClassloader());
| + return delivery(proxy, container, method, args);
| + }
| + finally
| + {
| + Thread.currentThread().setContextClassLoader(earlierClassLoader);
| + }
| +
| + }
| }
|
|
Thoughts? Anything obviously wrong with this approach?
View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4245976#4245976
Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4245976
More information about the jboss-dev-forums
mailing list