Can not access EJB from a Quartz job-class in JBoss 6.0.0CR1 - Quartz service is a MBean
jbossuser71 Dec 15, 2010 7:14 PMHi All,
I am using JBoss 6.0.0.CR1 release (in default configuration) and Quartz1.8.4 library - I have configurred Quartz as MBean Service.
As per Jboss/Quartz integration tutorial I have removed existing Quartz libraries from ${jboss}/server/common/lib and replace them with quartz-1.8.4.jar and quartz-jboss-1.8.4.jar
I have also removed "quartz-ra.rar" from the "${jboss}/server/default/deploy" folder and put the quartz service definition xml file in ${jboss}/default/deploy directory.
My workflow is: from my Startup-Servlet (WAR) I invoke an EJB which accesses Quartz scheduler service and creates jobs in quartz scheduler.
The Quartz service comes up fine and I can schedule jobs as long as my job class does not access any EJB.
But if my job class tries to access any of the EJBs deployed in JBoss, I get following error.
====================================
2010-12-15 14:43:17,623 ERROR [org.quartz.core.JobRunShell] (EdmQuartzScheduler_Worker-1) Job DEFAULT.EdmHoldJob threw an unhandled Exception: : java.lang.RuntimeException: Specified calling class, com.im.server.edm.api.HoldRemote could not be found for BaseClassLoader@100c0aa{vfs:///C:/Workspace/DM1.0/dependencies/repository/appserver/server/default/deploy/edm-quartz-service.xml}
at org.jboss.ejb3.common.lang.SerializableMethod.getClassFromName(SerializableMethod.java:311) [:1.0.2]
at org.jboss.ejb3.common.lang.SerializableMethod.getClassType(SerializableMethod.java:282) [:1.0.2]
at org.jboss.ejb3.common.lang.SerializableMethod.toMethod(SerializableMethod.java:233) [:1.0.2]
at org.jboss.ejb3.common.lang.SerializableMethod.toMethod(SerializableMethod.java:220) [:1.0.2]
at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:178) [:1.0.11]
at $Proxy199.issueHold(Unknown Source) at com.im.server.edm.jobs.EdmHoldJob.execute(EdmHoldJob.java:52)
at org.quartz.core.JobRunShell.run(JobRunShell.java:216) [:]
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549) [:]
Caused by: java.lang.ClassNotFoundException: com.im.server.edm.api.HoldRemote from BaseClassLoader@100c0aa{vfs:///C:/Workspace/DM1.0/dependencies/repository/appserver/server/default/deploy/edm-quartz-service.xml}
at org.jboss.classloader.spi.base.BaseClassLoader.loadClass(BaseClassLoader.java:480) [jboss-classloader.jar:2.2.0.Alpha9]
at java.lang.ClassLoader.loadClass(ClassLoader.java:248) [:1.6.0_18]
at java.lang.Class.forName0(Native Method) [:1.6.0_18]
at java.lang.Class.forName(Class.java:247) [:1.6.0_18]
at org.jboss.ejb3.common.classloader.util.PrimitiveClassLoadingUtil.loadClass(PrimitiveClassLoadingUtil.java:99) [:1.0.2]
at org.jboss.ejb3.common.lang.SerializableMethod.getClassFromName(SerializableMethod.java:307) [:1.0.2]
... 8 more
=============================================
I understand it is a class loader issue and since the Quartz MBean is loaded by BaseClassLoader and the EJBs are by different classloader, I can not access EJB from the job-class loaded by Quartz.
I found the following useful tutorial link, which is applicable for JBoss 4.2.2.GA. It has information for the similar classloading issue with Quartz.
http://community.jboss.org/wiki/HowtoconfigureaQuartzservice
Since my Job definition class does access other classes in ear, I need to deploy Quartz service after my ear is deployed.
So I have edited the quartz service definition as shown below.
=======================
<?xml version="1.0" encoding="UTF-8"?> <server>
<mbean code="org.quartz.ee.jmx.jboss.QuartzService"
name="user:service=QuartzService,name=QuartzService">
<depends>jboss.j2ee:service=EARDeployment,url='myapp.ear'</depends>
<attribute name="JndiName">Quartz</attribute>
<attribute name="Properties">
org.quartz.scheduler.instanceName = QuartzScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.xaTransacted = false
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 4
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
</attribute>
</mbean>
</server>
=======================
But still with this modification, when I am trying to access 'Qartz' from my WAR module, I get following NameNotFoundException.
=======================
15:13:32,962 ERROR [[/edm]] StandardWrapper.Throwable: javax.ejb.EJBException: java.lang.IllegalStateException: javax.naming.NameNotFoundException: Quartz not bound
at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.handleExceptionInOurTx(CMTTxInterceptor.java:183) [:0.0.1]
at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:251) [:0.0.1]
at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.required(CMTTxInterceptor.java:349) [:0.0.1]
at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.invoke(CMTTxInterceptor.java:209) [:0.0.1]
at org.jboss.ejb3.tx2.aop.CMTTxInterceptorWrapper.invoke(CMTTxInterceptorWrapper.java:52) [:0.0.1]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.Alpha3]
at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76) [:1.0.0.GA]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.Alpha3]
========================
In the same tutorial link, author talks about changing folowing line in ${jboss.server}/deploy/jboss-web.deployer/META-INF/jboss-service.xml file.
<attribute name="UseJBossWebLoader">false</attribute>
But in 6.0.0.CR1 release I could not locate this file.
Can anyone pls. tell me where this file is now being packaged in JBoss 6.x - or how can I resolve this issue?
Wondering if I instantiate Quartz as a Servlet, I may not face this classloading issue - am I right?
Thanks in advance.
- Kuntal