Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

Is there a programmatic way to determine which Apex classes in my Org are batchable (i.e. implement a batch interface)? I have looked at the Metadata API but it does not seem to have any method for this. Any help or pointers will be appreciated.

Thanks!

share|improve this question
add comment

2 Answers

You can tell if a class implements a specific interface by using instanceof. For example, given the following class:

global class ProcessAccounts implements Database.Batchable<Account> {
    ...
}

You can depend on the following:

System.assert(((object)new ProcessAccounts()) instanceof Database.batchable<Account>);
System.assert(((object)new ProcessAccounts()) instanceof Database.batchable<subject>);
// The following is a bug?
System.assert(((object)new ProcessAccounts()) instanceof database.batchable<string>);

Basically, the point here is that as long as the account can be cast into the appropriate interface, it is considered an instance of that interface; this method will tell you if the class is indeed batchable and therefore able to be scheduled with schedulebatch or executed with executebatch.

For now, it doesn't matter what parameter you use for the interface, it will return true if, and only if, the class implements database.batchable in some context. This should get you a full list of classes:

set<system.type> batchables = new set<system.type>();
for(apexclass c:[select name from apexclass]) {
    try {
        system.type t = system.type.forname(c.name);
        if(t != null && t.newinstance() instanceof database.batchable<sobject>) {
            batchables.add(t);
        }
    } catch(exception e) { }
}
system.debug(batchables);

With one caveat: it does not support batchable (or really, any) classes that do not have a default constructor. Make sure that your classes have a default constructor, and this code will work just fine.

share|improve this answer
    
How can he use this to check all classes in his org though? This seems to only work on a one by one case basis. –  drakored Feb 6 at 3:59
    
@drakored You're right. I'll update. –  sfdcfox Feb 6 at 4:03
1  
Keeping in mind that I can iterate this code base in less than 2 minutes by cycling all apexclass and using containsIgnoreCase on the body field (for finding bits in the code). This seems to be lacking a little. –  drakored Feb 6 at 4:21
1  
Ran for 5-7 minutes, failed because of something in one of the constructors. Nice solution, but no good for large orgs, or orgs calling ApexPages.addMessage/s in the constructor apparently (the exception I received was: System.Exception: ApexPages.addMessage can only be called from a Visualforce page). +1 for the nice solution, but it has some limits that make it a little unusable in certain cases like ours unfortunately. –  drakored Feb 6 at 4:28
1  
I have a code snippet I can share that I use in exec anon. The draw back to using containsIgnoreCase is that is has no recognition of the actual pattern of the class. If someone were to previously use the batchable interface, then comment just that part of the line out, it'd detect it as a proper use. –  drakored Feb 11 at 19:12
show 7 more comments

I don't think there's any way to get this. Perhaps you could just search the body of the class that you get from the Metadata API, or even pull it out in Apex by querying ApexClass and searching the body there?

The Tooling API's ApexClass object has a SymbolTable member which in turn has a member called interfaces which includes the information you're after. Maybe switching to that API would be the best approach? See the docs on SymbolTable here.

share|improve this answer
    
Just use InstanceOf. –  sfdcfox Feb 6 at 3:57
    
Heh... totally overlooked that. –  LaceySnr Feb 6 at 4:19
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.