Yesterday I wrote how to define Quartz-Jobs in JBoss AS. Generally such jobs try to use business logic, which is injected via @EJB. Currently in Version 5.1.0.GA this is not possible if you use the classloader-isolation. You will get the following (or similar) exception:
1 2 3 4 5 6 7 8 9 | Caused by: java.lang.RuntimeException: Can not find interface declared by Proxy in our CL + BaseClassLoader@92c904{vfsfile:...} 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 |
The reason for this ist that the Quartz-Service has another classloader as your application and the started job contains to the classloader of the Quartz-Service. There is also a bug posted. Maybe this will be possible in the near future.
One solution is to call a MBean from the job and this MBean injects the business logic via @EJB. The advantage of this solution is that you also can control and monitor the cronjob itselfs and can run the logic on demand via JMX-Console.
An example job would look like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | @MessageDriven(messageListenerInterface = StatefulJob.class, activationConfig = { @ActivationConfigProperty(propertyName = "cronTrigger", propertyValue = "0 0 0 ? * MON-SAT") }) @ResourceAdapter("quartz-ra.rar") @Depends(ImportDataManagement.ID) public class DailyUpdateJob implements StatefulJob { private static final Logger log = Logger .getLogger(DailyUpdateJob.class); public void execute(JobExecutionContext context) throws JobExecutionException { try { MBeanServer server = MBeanServerLocator.locate(); ImportDataManagement bp = (ImportDataManagement) MBeanProxyExt .create(ImportDataManagement.class, ImportDataManagement.ID, server); bp.importDaily(); } catch (Exception e) { log.error("run", e); } } } |
Helpful links: