Database.Batchable class is not global

ID

apex.correctness.batchable_global

Severity

high

Remediation Complexity

trivial

Remediation Risk

medium

Remediation Effort

low

Resource

Api Design

Language

Apex

Description

Reports a class implementing Database.Batchable that is declared public or private rather than global.

Rationale

A batch class is not called like ordinary code: Database.executeBatch instantiates it by name, and in a managed package or from another namespace only a global type is visible. Declared public, the class works in the org where it was written and disappears the moment it is packaged, scheduled from another namespace, or invoked from a subscriber org - and the failure is a runtime "invalid type" rather than a compile error. The Schedulable that enqueues it usually lives in the same package, which is why the gap shows up only after installation.

The following code illustrates the pattern detected by this rule:

// FLAGGED: Database.Batchable class is not global
public class AccountRollupBatch implements Database.Batchable<SObject> {
    public Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator('SELECT Id FROM Account');
    }
    public void execute(Database.BatchableContext bc, List<SObject> scope) {
        update scope;
    }
    public void finish(Database.BatchableContext bc) {
        System.debug('done');
    }
}

Remediation

Declare the class global and mark start, execute and finish global too, since the interface members must match the class visibility. Keep public only where the batch is internal to one org and will never be packaged - and note that global is a permanent API commitment in a managed package, so settle the signature before it ships.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved