Rather than creating a separate Schedulable class which executes my Batchable class (which in turn has a callout), shouldn't I be able to have my Batchable class also implement the Schedulable interface and in the execute(SchedulableContext) method, new up the same Batchable class and pass it to the Database.executeBatch method?

This works fine when I execute the schedule from the dev console like so:

Batch_APNEmail batchApex = new Batch_APNEmail();

But when I create a scheduled job through the Salesforce web interface and configure it to execute daily at 9am, it throws the exception:

System.CalloutException: Callout from scheduled Apex not supported.

My schedulable/batchable class declaration looks like this:

global class Batch_APNEmail implements Database.Batchable<sObject>, Database.Stateful, Database.AllowsCallouts, Schedulable

My Scheduleable execute method within the schedulable/batchable class looks like this:

global void execute(SchedulableContext sc){
    Batch_APNEmail batchAPN = new Batch_APNEmail();
    Database.executeBatch(batchAPN, 1);

Here's a unit test which runs successfully:

@isTest static void test_Schedule(){

    // Setup the mock callouts with static resources

        Batch_APNEmail batchApex = new Batch_APNEmail();

    // Verify the callouts were made
    List<Academic_Progress_Notification__c> apns = [SELECT Emailed_Student__c FROM Academic_Progress_Notification__c];
    for (Academic_Progress_Notification__c apn : apns){
        System.assertEquals(apn.Emailed_Student__c != null, true);

1 Answer 1


Yes. In general, you can combine as many interfaces as you want within a single class, so long as they are all compatible. Using the scheduable and batchable interface within the same class just means you have to implement all four methods. Your class will start off like:

public class x implements Database.Batchable<Object>, Database.AllowCallouts, Scheduable {

As an aside, you could also use Scheduable to call a future method, which may be simpler if you need just one callout (or, less than the 10 limit). In which case:

@future(callout=true) public static void doCallout() {
  • 1
    From the looks of his question he is doing exactly as you state in your answer yet he is getting issues. Do you see positive results with a callout using your methods? If so then the OP has something else going on and will need to post more code.
    – Eric
    Aug 13, 2014 at 14:27
  • 1
    No, you have to use Test.startTest and Test.stopTest. See salesforce.com/us/developer/docs/apexcode/Content/… for information on a proper test.
    – sfdcfox
    Aug 14, 2014 at 0:18
  • 2
    That's an incorrect test. You must schedule the class and let it execute naturally. Do not call execute(null), because then it is being called in the wrong context.
    – sfdcfox
    Aug 14, 2014 at 14:39
  • 2
    The point of test.stoptest is to execute any asynchronous code that's been called. Future, scheduled, and batch code all fall into this category. Without this context switch, you can't prove that code is working in the intended fashion. For example, the scheduablecontext value being null isn't a real world use case. All scheduled executions have a Scheduable context.
    – sfdcfox
    Aug 19, 2014 at 15:13
  • 2
    Also, as I've pointed out, certain calls aren't allowed in certain contexts. The only way to catch this problem is to unit test or live test. Since the scheduler is failing in the real world, the unit test isn't matching the behavior.
    – sfdcfox
    Aug 19, 2014 at 15:13

You must log in to answer this question.

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