How to deploy apex classes that are scheduled

Dan Appleman presented a pattern in his Dreamforce 2013 session Design Patterns for Asynchronous Apex.

You can download the code on Dan’s Dreamforce 13 page.

The basic design is that you have a ScheduledDispatcher Class which uses Type.forName to dynamically create a ScheduleHandler class. The ScheduledDispatcher class is the one that gets locked, but the handler isn’t, so you can update it.

global class ScheduledDispatcher Implements Schedulable {
    public Interface IScheduleDispatched 
    { 
        void execute(SchedulableContext sc); 
    } 

    global void execute(SchedulableContext sc) 
    {
        Type targettype = Type.forName('ScheduleHandler');   
        if(targettype!=null) {
            IScheduleDispatched obj = (IScheduleDispatched)targettype.NewInstance();
            obj.execute(sc);   
        } 
    } 
}

public class ScheduleHandler implements ScheduledDispatcher.IScheduleDispatched {

    public void execute(SchedulableContext sc)
    {

    } 
}

His book is worth every penny and every one of his Dreamforce sessions is a must watch.


In Winter 15, there is a new option to deploy jobs while active. Here are the release notes: http://docs.releasenotes.salesforce.com/en-us/winter15/release-notes/rn_deploy_with_jobs.htm


How can we have scheduled jobs and deploy updates to the classes that are scheduled?

After extensive experimentation today it is clear Dan Appleman's solution presented in the post above is no longer relevant.

This pattern does not work to enable deployment. I tested this through the Ant tool. Despite having Appleman's code verbatim in an otherwise empty packaging org deployments that changed scheduled code continued to be blocked. Perhaps it would work if only deploying a single file but it does not work when driven by a package.xml listing all the files in the package.

Furthermore it does not seem that this pattern is required when installing a managed package. I was unable to cause a failure upon install despite having scheduled jobs which are changed in the new release of the managed package. It seems that package developers can rest assured that scheduled jobs will not place their packages into a situation where upgrades can not be pushed to clients.

In summary: it is likely that the solution given by Appleman is no longer relevant. Salesforce revamped their scheduling code in the interim which is likely what changed this behavior. The Winter '14 Release Notes mention a new scheduling infrastructure:

To take advantage of a new and improved scheduling infrastructure introduced in Summer ’13, Apex jobs scheduled before Summer ’13 are upgraded to run on this new scheduling infrastructure.

The unsavory solution that remains is to use the deployment setting to prevent this check and hope that you don't need the safety net you are disabling. This will at least allow you to continue to develop even when testing scheduled jobs.