[SalesForce] Can hidden classes in managed packages be scheduled programmatically

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?

Best Answer

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);
        }
    }



}
Related Topic