1

My use case: Any time I update code that is related to a currently scheduled job, that job has to first be unscheduled, then rescheduled after the code update. Doing this manually is a pain!

My plan was to a create a couple utility methods in Apex: one that would delete all scheduled jobs using the CronTrigger object, and a second that would programmatically reschedule all jobs I have in my system.

 

The issue: That second method, which reschedules all jobs, is running into issues when it comes to hidden classes in managed packages. If there's a schedulable class in a managed package, I can use the scheduling UI to schedule the job, but apparently running a line of code like

system.schedule('Schedulable class in managed package', '0 0 22 ? * 1', new HiddenClass());

will throw an error: Invalid type: HiddenClass

 

Question: Is my approach possible, given the hidden nature of classess in managed packages? Is there a better way to update apex that is related to scheduled jobs, without having to delete and reschedule those jobs using the UI each time?

4
  • 1
    Look at the code here: gist.github.com/gbutt/11151983 - which will allow your package to update batch class code even if it is scheduled
    – Eric
    Commented Jul 24, 2015 at 18:15
  • @Eric I've seen this code sample before. But if I understand it correctly, it will not solve the problem of not being able to programmatically reschedule jobs for classes that are part of managed packages I don't have access to.
    – smohyee
    Commented Jul 24, 2015 at 18:19
  • 1
    You understand your use case better than I, but you would not have to unschedule your packages scheduled code in order to update the packages code - Or maybe I misunderstood your question, as I am assuming you were the package owner.
    – Eric
    Commented Jul 24, 2015 at 18:23
  • Thinking it through a bit more, I take your point: I wouldn't have to reschedule jobs from managed packages if I didn't have to delete them in the first place, and I wouldn't have to delete any jobs if they are all tied to this schedule dispatcher class instead of my other code.
    – smohyee
    Commented Jul 24, 2015 at 18:25

2 Answers 2

2

A framework to allow your classes to not be locked due to being scheduled (Espiecally in a managed package) can be accomplished via the code located here:

https://gist.github.com/gbutt/11151983

Reposting code here (Code written by git use gbutt)

/***
This class can be used to schedule any scheduled job without risk of locking the class.
DO NOT CHANGE THIS CLASS! It is locked by the scheduler. Instead make changes to ScheduledHelper or your own IScheduleDispatched class
To use:
    1) Create a new class to handle your job. This class should implement ScheduledDispatcher.IScheduleDispatched
    2) Create a new instance of ScheduledDispatcher with the type of your new class.
    3) Schedule the ScheduledDispatcher instead of directly scheduling your new class.
    See ScheduledRenewalsHandler for a working example.
***/
global class ScheduledDispatcher implements Schedulable {
    private Type targetType; 

    public ScheduledDispatcher(Type targetType) {
        System.debug('Creating new dispatcher for class: ' + targetType.getName());
        this.targetType = targetType;
    }

    global void execute(SchedulableContext sc) {
        ((IScheduleDispatched)targetType.newInstance()).execute(sc); 
    }


    public interface IScheduleDispatched {
        void execute(SchedulableContext sc);
    }
}

An example class I used to implement it:

public class ScheduledDispatcher Implements Schedulable{


    public Interface IScheduleDispached{
        void execute(SchedulableContext sc);
    }

    public void execute(SchedulableContext sc){

        Type targetType = Type.forName('CLASSNAME');
        if(targetType != null){
            IScheduleDispached obj = (IScheduleDispached)targetType.newInstance();
            obj.execute(sc);
        }
    }



}
1

WOOHOO! The 2015 release now allows deployment of code without regard to currently scheduled jobs! Looks like my question is no longer relevant.

http://docs.releasenotes.salesforce.com/en-us/winter15/release-notes/rn_deploy_with_jobs.htm

Edit: Although, it's worth noting that this only works when updating the code via the Metadata API. So presumably using the Tooling API will still cause problems

1
  • 2
    Even using the Metadata API, you'll run into a problem occasionally if the deployment happens to coincide with a scheduler running that very second. It can cause the scheduler to fail until the next run. This may or may not matter, but you should at least be aware of it.
    – sfdcfox
    Commented Jul 24, 2015 at 21:57

You must log in to answer this question.

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