6

I often run into this error message:

This schedulable class has jobs pending or in progress
You can bypass this error by allowing deployments with Apex jobs in the Deployment Settings page in Setup.

When I try and update an Apex class which is scheduled in:

Setup > Scheduled Jobs

Is this same issue liable to block/stop a Managed Package from updating if one of the internal Apex classes is scheduled and the Allow deployments of components when corresponding Apex jobs are pending or in progress. setting isn't enabled?

1
  • 2
    P.S. I asked on social media to fact-check this. Maybe someone has more solid documentation/official word on this. – sfdcfox Dec 8 '20 at 8:32
4

According to this question on the Developerforce platform, a user discovered that you can install an update even while a Schedueable class is scheduled.

I can't find any documentation on the matter, but this makes sense; ISVs need to be able to push out updates, sometimes forcefully (see Push Upgrades), which wouldn't be possible if a user could just permanently lock the package from upgrading by scheduling it.

For example, let's say I wanted to prevent a package from updating, I could deploy this code to production:

public class HahaIBlockedYourUpdate implements Schedulable {
  public void execute(SchedulableContext) {
    SomeNamespace.SomeClassFromNS value;
  }
}

Schedule the class, and "presto!", the ISV can no longer push updates to the subscriber if they have even a single global class in their package (since you can't access public/private classes inside a package).

So, while undocumented, it should be safe to update the class if you need to. Do be aware that you may need to notify users of your package update, since the class may break if you make certain changes to the class. This is because a scheduled class is serialized when it is scheduled, so changing variable names or types may affect the serialized state, resulting in runtime errors.

You should be very careful changing your Schedulable class, but if you need to make an update, you won't need to worry about previously scheduled classes from blocking an update.

3

Just to add to this, it definitely use to be an issue in 1GP packages, which is why you see posts about it. I think it was Dan Appleman who suggested using this pattern in scheduled jobs to avoid that issue, and I still use it today. So I think sfdcfox is correct that managed packages basically install as if "Allow deployments of components when corresponding Apex jobs are pending or in progress" is turned on, but something like the pattern below would also avoid likely conflicts if you start encountering them

global class KWDATA_Scheduler implements Schedulable {

    global void execute(SchedulableContext sc) {
        Type t = Type.forName('KWDATA_RequestData');
        KWDATA_RequestData kwd = (KWDATA_RequestData) t.newinstance();
        kwd.RequestData();
    }

}
1
  • 2
    Good point. I prefer to use this pattern for our unmanaged classes to avoid deployment conflicts. Unfortunately, sometimes you do need to update the actual state of the Schedulable class (e.g. it needs serialized data for whatever reason). Still, I'd definitely recommend this when possible. – sfdcfox Dec 8 '20 at 15:05

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.