Find your content:

Search form

You are here

Linking CronTrigger sObjects to Scheduled Jobs listings

 
Share

When using System.schedule to add apex jobs to the scheduled jobs listing it creates a CronTrigger sObject containing the expression determining when the job is set to run. However this CronTrigger record does not contain the name of the scheduled job or the apex class to be run.

Likewise when viewing a scheduled job that was scheduled via System.schedule from the Setup > Monitoring > Scheduled Jobs page there is no "Manage" link that shows what apex class is being scheduled to run, only the job name.

It seems impossible from this to tell what apex class a scheduled job will run, and inversely what the job name of a CronTrigger is.

Am I missing something, or is there a huge gap in the administrative ability and APIs around scheduled apex?


Attribution to: ca_peterson

Possible Suggestion/Solution #1

Q1 - What's the job name?

This is now pretty straightforward now that the ideas in @daniel's answer have been implemented (yes it does happen, rarely).

CronTrigger cron = [SELECT CronJobDetail.Name FROM CronTrigger WHERE Id = :jobId];
System.debug(cron.CronJobDetail.Name);

Q2 - What's the apex class for the job?

Unfortunately there isn't any direct link between the CronTrigger table and the related apex class id (at least that they expose). See the these two ideas to vote it up. That said you've got some options.

Option 1 - Setup Menu

Sometimes you can get it from the setup. Go to setup->monitor->jobs->scheduled jobs, and you'll see a list of all scheduled jobs. For apex classes that were scheduled through the 'Schedule Apex' button in setup->develop->apex classes, you'll see a 'Manage' link next to the job. Click that and you'll see the class name associated with that job.

Option 2 - Test Delete Schedulable Classes

However, it turns out the metadata api is kind enough to return the id of the CronTrigger records associated with an apex class if you try and delete it.

First you'll need to get a list of all schedulable apex classes then you org and then try and delete them with the metadata api. If say there was just one, MySchedulableClass you would you would have the following destructiveChanges.xml

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>MySchedulableClass</members>
        <name>ApexClass</name>
    </types>
    <version>41.0</version>
</Package>

If you do a test deployment, you'll get an error like the following which includes the crontrigger ids (they start with 08e)

BUILD FAILED
/Users/yourname/ant/sfse/build.xml:95: The following error occurred while executing this line:
/Users/yourname/ant/sfse/build.xml:55: 
*********** DEPLOYMENT FAILED ***********
Request ID: 0AfXXXXXXXXXXXXXXX

All Component Failures:
1.  classes/MySchedulableClass.cls -- Error: This apex class is referenced elsewhere in salesforce.com.  Remove the usage and try again. : Scheduled Jobs - 08eXXXXXXXXXXXX. This Schedulable class is in use. : Apex Class.

*********** DEPLOYMENT FAILED ***********

Then it's just a matter of searching those errors for the id of the particular CronTrigger you're interested in and you'll have your answer.

CAVEAT I expect this approach won't work for schedulable classes that are part of a managed package since you won't be able to delete those with the metadata api, but who knows, worth trying.

Option 3 - Correlate with AsyncApexJob Table

Based on @michael's answer. In most cases schedulable jobs will start a batch job. If that's the case you can look at the last fired date for the scheduled jobs list and try and find the corresponding job in the AsyncApexJob table based on the created date for the AsyncApexJob, then you can inspect the ApexClassId column.


Attribution to: Ralph Callaway

Possible Suggestion/Solution #2

There doesn't currently appear to be any mechanism for determining the apex class or the name of the scheduled job from Apex or via the API (See Ideas:CronTrigger Name field needs to be exposed).

As a stop gap measure, you could create a custom object or setting and manually map from the CronTriggerId returned by System.schedule() and the data that you require (ApexClass name or Id). Reference - Need a way to programatically change or delete a Scheduled Job


Attribution to: Daniel Ballinger

Possible Suggestion/Solution #3

Rich Van Dev posted a comment on an idea in the IdeaExchange that contained a really nice hack/work-around:

There is a way to do this though it is undocumented and could be subject to breaking with new SF releases.

It is possible to add text after the year element of the Cron Expression - this text is ignored when the cron expression is parsed however it is available when querying the CronTrigger by CronExpression with a filter like "where CronExpression LIKE '% NAMEOFMYSCHEDULEDJOB'".

Example:

  System.schedule('My Job Name', '0 59 23 31 12 ? 2013 MyJobName', new MyJob());

  List<CronTrigger> listCronTrigger  = [
      SELECT Id, OwnerId, CronExpression 
      FROM CronTrigger 
      WHERE CronExpression like '% MyJobName'];
  system.debug(listCronTrigger);

Also, the idea is scheduled for release in Winter 2014.


Attribution to: Matt K

Possible Suggestion/Solution #4

I use the following thing to match the CronTrigger with AsyncApexJob object which has information about Schedulable class which is scheduled.

I join these two tables by CreatedDate field.

It appears if these jobs are scheduled by a user, it can 100% match the CronTrigger with AsyncApexJob object and through it retrieve the name of Schedulable class which is scheduled.

However, if I schedule it from code when several scheduled jobs are being scheduled in the same second, this doesn't work. So I could just wait a second between scheduling jobs but it will hit 10000 milliseconds Apex CPU Time Limit if I had more than 9 Schedulable Jobs.

Here is my code snippet to backup scheduled jobs https://docs.google.com/document/d/1Rj2CFnPcFs3xC82N2snX1j21k9TlIi3325MQmA0R8qg and here to restore scheduled jobs from backup (user should change in the first line name of the debug object which contains the backup) https://docs.google.com/document/d/162ChaB_6Lkgp89bHhbKZjp7tHQPpYODC5gQnX9vxI_I

Also there is here debug log object xml which I use to put backup in JSON format inside one of its fields. https://docs.google.com/document/d/1UoM64UsTzIPKkTQdfaQ0D8k85aSL_o6BlwJOW-lbW1g


Attribution to: Patlatus
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/374

My Block Status

My Block Content