1

I have 20 scheduled APEX classes, and every time I want to change one or deploy new APEX I get an error for every Scheduled APEX test class like this:

Failure Message: "System.AsyncException: The Apex job named "ClientCare_AfterAction_MonSch" is already scheduled for execution.", Failure Stack Trace: "Class.ClientCare_AfterAction_MonSch.scheduleNow: line 36, column 1 Class.ClientCare_AfterAction_MonSch.execute: line 16, column 1"

So I have to delete every scheduled job, deploy the code, then reschedule. It's rather annoying.

I've asked this question before, and received a working answer (to change the name of the Scheduled job in the test class), but have since had to change the Schedulable class which has made the problem come up again and the previous solution no longer works.

Scheduable Class:

global class ClientCare_FundUpdate_MonthlySch implements Schedulable{


global void execute(SchedulableContext SC) {
    ClientCare_FundUpdate_MonthlyEmail CCBatch = new ClientCare_FundUpdate_MonthlyEmail(); 
    database.executebatch(CCBatch,100);

   // this section of code will abort the current schedule job 
try { 
system.abortJob(sc.getTriggerId()); 
} catch (exception e) {system.debug('ClientCare_FundUpdate_MonthlySch schedule job exception while aborting:' + e);} 


// reschedule the job 
system.debug('ClientCare_FundUpdate_MonthlySch schedule job executing'); 
scheduleNow();

} 


global static void scheduleNow() { 

// this section of code will schedule the next execution 1 minute from now 
datetime thisTime = system.now().addHours(24); 
integer minute = thisTime.minute(); 
integer second = thisTime.second(); 
integer hour = thisTime.hour(); 
integer year = thisTime.year(); 
integer month = thisTime.month(); 
integer day = thisTime.day(); 

String timeStamp = second + ' ' + minute + ' ' + hour + ' ' + day + ' ' + month + ' ? ' + year; 
string jobName = 'ClientCare_FundUpdate_MonthlySch'; 

ClientCare_FundUpdate_MonthlySch p = new ClientCare_FundUpdate_MonthlySch(); 
system.schedule(jobName, timeStamp , p); 

/**    
ClientCare_FundUpdate_MonthlySch m = new  ClientCare_FundUpdate_MonthlySch();
String sch = '0 0 5 1 * ? * ' ;
system.schedule('ClientCare_FundUpdate_MonthlySch', sch, m);
*/
}
}

Test Class:

public static testmethod void DailySchEmailJobtest() {

   Test.startTest();
   String sch = '0 0 5 ? * * * ' ;
   String jobId = System.schedule('ClientCare_FundUpdate_MonthlySch_Test',sch, new ClientCare_FundUpdate_MonthlySch());
   Test.stopTest();
}        
1

3 Answers 3

3

You can't deploy apex without running tests in production. The solution to this issue was provided here

How to deploy apex classes that are scheduled

1
  • I added/updated the classes, scheduled it, then I changed my batch class and tried to upload it and got the same error. Apex job is already scheduled for execution.
    – Jennifer
    Commented Jun 7, 2014 at 19:05
0

From what I can tell the problem is not the test but that you can't deploy a class that is scheduled. If you instante the class at runtime you shouldn't get that error.

private static final String BATCH_CLASS = 'ClientCare_AfterAction_MonSch';

global void execute(System.SchedulableContext SC) {
    Type t = Type.forName(BATCH_CLASS);
    Database.Batchable<sObject> batchClass = (Database.Batchable<sObject>) t.newInstance();
    Database.executeBatch(batchClass);
}
0

I had to change the test class so that it removed all scheduled jobs before starting the test. Now I can import changes to the code w/o the error:

@isTest static void DailySchEmailJobtest() {
  final Id cronTriggerId;
  for (CronTrigger cronTrigger : [SELECT Id FROM CronTrigger]) {System.abortJob(cronTrigger.Id);}

System.assertEquals(0, [SELECT COUNT()
                            FROM AsyncApexJob
                            WHERE ApexClassId IN (SELECT Id FROM ApexClass WHERE NamespacePrefix = null AND Name = 'ClientCare_FundUpdate_MonthlyEmail')]);
    Test.startTest();
    cronTriggerId = System.schedule('ScheduledJob', '0 0 * * * ?', new ClientCare_FundUpdate_MonthlySch());
    Test.stopTest();
    System.assertEquals(1, [SELECT COUNT()
                            FROM AsyncApexJob
                            WHERE ApexClassId IN (SELECT Id FROM ApexClass WHERE NamespacePrefix = null AND Name = 'ClientCare_FundUpdate_MonthlyEmail')]);
    System.assertEquals('Queued', [SELECT Status
                                   FROM AsyncApexJob
                                   WHERE ApexClassId IN (SELECT Id FROM ApexClass WHERE NamespacePrefix = null AND Name = 'ClientCare_FundUpdate_MonthlyEmail')].Status);
}     

}

You must log in to answer this question.

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