task scheduling in JBoss

In many projects there is a requirement for cron-like task scheduling, be it for batch processing, automatic system maintenance or some other regular job. There are a few blocks which need to be put into place to assure the scheduled task runs using the correct server role.

The following file (aptly called “scheduler-service.xml”) configures the actual scheduling

<?xml version="1.0" encoding="UTF-8"?>
<server>
    <mbean code="org.jboss.varia.scheduler.Scheduler" name=":service=My-Scheduler">
        <attribute name="StartAtStartup">true</attribute>
        <attribute name="SchedulableClass">fully.qualified.ClassName</attribute>
        <attribute name="SchedulableArguments"></attribute>
        <attribute name="SchedulableArgumentTypes"></attribute>
        <attribute name="InitialStartDate">0</attribute>
        <!-- schedule 5 seconds -->
        <attribute name="SchedulePeriod">5000</attribute>
        <attribute name="InitialRepetitions">-1</attribute>

        <depends>jboss.j2ee:module=defining-jar.jar,service=EJB3</depends>
    </mbean>
</server>

This file can contain as many scheduled mbeans as needed as longs as you give them a unique name. The depends tag at the bottom allows you assure the jar file with the actual definitions is deployed before the scheduled class.

This file can either be placed in the JBoss deploy directory, or referenced from the “jboss-app.xml” file

<?xml version="1.0" encoding="UTF-8"?>
<jboss-app>
    <module-order>strict</module-order>
    <!-- ..... other stuff which needs to be in here -->
    <module>
        <service>META-INF/scheduler-service.xml</service>
    </module>
</jboss-app>

The scheduled class needs to implement the “org.jboss.varia.scheduler.Schedulable”. When using maven, the dependency can be defined as

<dependency>
    <groupId>be.progs.org.jboss</groupId>
    <artifactId>scheduler-plugin</artifactId>
    <version>4.2.2.GA</version>
    <scope>provided</scope>
</dependency>

Which needs the following repository
<repositories>
    <repository>
        <id>progs</id>
        <url>http://maven.progs.be/m2repo</url>
    </repository>
</repositories>

The scheduled class can then look like this. In this example, we immediately call a (local) stateless session bean to assure we are running using the correct authorizations (by forcing the role).

public class ClassName
    implements Schedulable
{
    public void perform( Date now, long remainingRepetitions )
    {
        try
        {
            ScheduledEJB scheduled = EJBUtil.lookup( "fully.qualified.ScheduledEJB", ScheduledEJB.class );
            scheduled.doScheduled();
        }
        catch ( javax.naming.NamingException ne )
        {
            throw new RuntimeException( ne );
        }
    }
}

The stateless bean has the following interface

@Local
public interface ScheduledEJB
{
    public void doScheduled();
}

And a dummy implementation looks like this

@Stateless
@Local( ScheduledEJB.class )
@LocalBinding( jndiBinding = "fully.qualified.ScheduledEJB" )
@SecurityDomain( "mySecurityDomain" )
@RunAs( "LocalUser" )
public class ScheduledBean
    implements ScheduledEJB
{
    private static final Logger log = Logger.getLogger( ScheduledBean.class );

    public void doScheduled()
    {
        log.info( "updateMatcherIndex called" );
    }
}

2 Comments

  1. Alexandre Verri says:

    Excellent post. I was looking for exactly this solution.

    Thank you.

  2. Maelig says:

    Saved my life, thanks 😉

Leave a Reply

Your email address will not be published. Required fields are marked *

question razz sad evil exclaim smile redface biggrin surprised eek confused cool lol mad twisted rolleyes wink idea arrow neutral cry mrgreen

*