34

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?

32

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.

  • 5
    His book is sitting on my desk. Guess I better actually open it! – Daniel Hoechst Jan 17 '14 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" – Shinya Koizumi Jan 17 '14 at 17:21
  • @ShinyaKoizumi - Hmmm...that's probably a different issue. Take a look at this question and this one. – Peter Knolle Jan 17 '14 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 Apr 29 '14 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 Apr 29 '14 at 12:03
20

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

  • this would have to be set in each customers org in the case of managed package though correct? – Phil B Feb 8 '16 at 13:58
  • That would be my guess. – Daniel Hoechst Feb 8 '16 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 Mar 1 at 6:44
6

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.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.