35

This is related to Is there any way to unschedule an apex scheduled job programmatically?. I noticed user320 mentioned there is a way to use Type.forName to decouple your classes from the scheduled jobs, but no details were given.

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

4 Answers 4

34

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.

9
  • 6
    His book is sitting on my desk. Guess I better actually open it! Commented Jan 17, 2014 at 14:24
  • I tried this one and it gives you ability to save the ScheduleHandler file from eclipse but when deploying with ant it still gives me error saying "Apex class has Batchable or Future jobs pending or in progress; Schedulable class has jobs pending or in progress" Commented Jan 17, 2014 at 17:21
  • @ShinyaKoizumi - Hmmm...that's probably a different issue. Take a look at this question and this one. Commented Jan 17, 2014 at 17:34
  • 1
    Interesting. I was going to write a post about this. Appleman beat me to it. I suppose I need to step up my game and visit Dreamforce.
    – sfdcfox
    Commented Apr 29, 2014 at 1:40
  • 1
    @PeterKnolle I actually created something like that on the way to the version I use now, which asks each batch in an organization if it would like to run, and if so, executes it.
    – sfdcfox
    Commented Apr 29, 2014 at 12:03
22

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

3
  • this would have to be set in each customers org in the case of managed package though correct?
    – Phil B
    Commented Feb 8, 2016 at 13:58
  • That would be my guess. Commented Feb 8, 2016 at 13:59
  • this only applies when you are deploying with the meta-data API, thus most IDE's will still error (they typically use tooling-api)
    – NSjonas
    Commented Mar 1, 2019 at 6:44
8

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.

1
  • I think it likely that the old work around of dynamic initialization wasn't guaranteed to play nice either.
    – NSjonas
    Commented Mar 1, 2019 at 6:53
0

Setup -> Deployment Settings -> check Allow deployments of components when corresponding Apex jobs are pending or in progress.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .