Alternatives to Quartz Scheduler in JBoss EAP 8 / 7 / 6

Solution Verified - Updated -

Environment

  • Red Hat JBoss Enterprise Application Platform (EAP)
    • 8.x
    • 7.x
    • 6.x

Issue

  • In our application we are using the Quartz framework for scheduling jobs.
  • We are looking for migration documentation on how to port Quartz from JBoss EAP 5.x to EAP 6.0
  • Does Red Hat support Quartz or any equivalent in EAP 6? We have some job managed via Quartz in JBoss EAP 4. In JBoss EAP 6 can we use Quartz or another feature?
  • Is it possible to deploy quartz-ra.rar in EAP 6 and use MDB as a cron trigger like we do in EAP 5?
  • Is Quartz a JCA standard and can be deployed in JEE container or the "quartz-ra.rar" was proprietary of EAP 5?

Resolution

In JBoss EAP 4 / EAP 5, The Quartz Job Scheduler is used internally by the Java EE Timer Service and Seam Asynchronous methods with the Quartz Dispatcher. It is only supported within these contexts1.

JavaEE 6 has updated the EJB Timer service to include a scheduling capability similar to Quartz, see The Java EE 6 Tutorial2 and the example below. You can also use @Timeout and the TimerService API to schedule and cancel timers. This is the recommended way to do timers and scheduling as it is the JavaEE 6 specification.

JBoss EAP 6 does not include Quartz as it does not use Quartz for implementing EJB Timers. If your application depends on Quartz and you cannot use EJB Timers, then you will need to package Quartz with your application and bootstrap it or work though the Quartz community to get a new release of Quartz with an updated QuartzService MBean.

Note: In JBoss EAP 6.1 and later the old JBoss MBean support classes ServiceMBean and ServiceMBeanSupport have been included to allow old MBean implemenations that extended them to be deployed3.

Using JavaEE Timers

Below is an example of using JavaEE 6 EJB Timers with a Cron like schedule configuration:

import java.util.Date;
import javax.annotation.Resource;
import javax.ejb.Schedule;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;

@Singleton
@Startup()
public class TimerScheduleBean
{
  // Here we inject a reference to the timerService
  @Resource
  private TimerService timerService;

  // Schedule timer will fire every 5 seconds
  @Schedule(second="*/5", minute="*", hour="*")
  public void scheduledTimeout()
  {
    System.out.println("Schedule Timer fired - " + new Date());
  }
}

Including Quartz in your application or a custom module in JBoss EAP 6

If you want to use Quartz, you can package it in your application or create a JBoss Module for it by placing the quart jars in $JBOSS_HOME/modules/org/quartz/main/ then create a $JBOSS_HOME/modules/org/quartz/main/module.xml containing something such as:

<module xmlns="urn:jboss:module:1.1" name="org.quartz">
  <resources>
    <resource-root path="quartz-all.jar"/>
  </resources>
  <dependencies>
    <module name="org.slf4j"/>
    <module name="javax.api"/>
  </dependencies>
</module>

You can create the above custom module by the following CLI command:

module add --name=org.quartz --resources=/path/to/quartz-all.jar --dependencies=javax.api,org.slf4j

Then any application that needs to use your Quartz classes can add a org.quartz to the deployment's META-INF/MANIFEST.MF Dependencies: section or by adding org.quartz as a depdendency to the top level deployment's jboss-deployment-structure.xml45.

If you need Quartz to be bootstrapped when the application is deployed, use a JavaEE 6 Singleton with @PostConstruct such as:

@javax.ejb.Singleton
@javax.ejb.Startup
public class QuartzBootstrapSingleton
{
    private Logger log = Logger.getLogger(this.getClass().getName());

    @javax.annotation.PostConstruct
    public void start()
    {
       // INSERT Quartz bootstrapping here
    }

    @javax.annotation.PreDestroy
    public void stop()
    {
      // INSERT Quartz shutdown / clean up here
    }
}

References:


  1. JBoss Enterprise Application Platform Component Details
    http://www.redhat.com/resourcelibrary/articles/jboss-enterprise-application-platform-components ↩︎

  2. The Java EE 6 Tutorial - Using the Timer Service
    http://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html ↩︎

  3. AS7-887 - Support legacy ServiceMBeans in SAR deployments
    https://issues.jboss.org/browse/AS7-887 ↩︎

  4. How to create Custom Modules in JBoss EAP6
    https://access.redhat.com/site/solutions/195403 ↩︎

  5. Class Loading in AS7
    https://docs.jboss.org/author/display/AS71/Class+Loading+in+AS7 ↩︎

Root Cause

Quartz Scheduler is not part of the Java EE specification, it was an implementation detail used by earlier versions of JBoss for EJB timer implementation, but is not longer used.

Note: Some versions of Quartz included an mbean implementation designed for JBoss (org.quartz.ee.jmx.jboss.QuartzService). This implementation extended some JBoss interal helper classes such as org.jboss.system.ServiceMBeanSupport. These classes do not exist in JBoss EAP 6 and thus the Quartz MBean org.quartz.ee.jmx.jboss.QuartzService will not work in JBoss EAP 6.0. If you are using this, see the section below "Including Quartz in your application or a custom module in JBoss EAP 6". The ServiceMBeanSupport MBean service classes are being added in JBoss EAP 6.1, however the QuartzService mbean uses other things which do not exist in JBoss EAP 6.x so it would still require some changes. The mbean is depending on these mbeans which do not exist, so the mbean depends would need to be updated.

<depends>jboss:service=Naming</depends>
<depends>jboss.jca:service=ManagedConnectionPool,name=jdbc/feaDataSource</depends>
<depends>jboss.jca:service=DataSourceBinding,name=jdbc/feaDataSource</depends>
<depends>jboss.jca:service=ManagedConnectionFactory,name=jdbc/feaDataSource</depends>
<depends>jboss.jca:service=XATxCM,name=jdbc/feaDataSource</depends>

The QuartzService MBean is trying to get access to the MBean server but is doing it in a remote way by using JNDI at jnp:localhost and looking for jmx/rmi/RMIAdaptor, but RMIAdaptor is not bound in EAP 6. So the best option would be for the Quartz community to update the mbean use the standard MBean specification.

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.

Comments