skip to content

JobOperator

JobOperator is the operations-facing API: start, stop, restart, abandon, list running executions, and start the next instance from an incrementer. It is what an admin UI or ops endpoint would call, and interviewers ask how a running job gets stopped.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

explore

questions

5

What is Spring Batch's JobOperator, and how does it differ from JobLauncher?

level: juniorimportance: must knowfreq 50%

answer

  1. Operator = admin facade, Launcher = runner
  2. Simple types: names + ids + Properties
  3. SimpleJobOperator needs Launcher+Registry+Repository+Explorer
  4. Job must be in JobRegistry (resolve by name)
  5. start/stop/restart/abandon/startNextInstance

basics

~10 s

JobOperator is an operations-facing facade for controlling jobs — start, stop, restart, and abandon executions using simple types like job names and execution ids. JobLauncher just runs a Job you already have wired.

solid answer

~40 s

JobLauncher has a single job: take a Job object plus JobParameters and run it, returning a JobExecution. JobOperator is a higher-level, operations-oriented facade meant for administrators, CLIs, JMX, or a web console. It works with simple types — String job names, long execution/instance ids, Properties — so callers don't need Java references to Job or JobParameters. It exposes start(jobName, params), startNextInstance(jobName), restart(executionId), stop(executionId), abandon(executionId), plus read/query methods like getRunningExecutions(jobName), getJobNames(), and getSummary(). Internally SimpleJobOperator delegates the actual running to a JobLauncher and looks jobs up via a JobRegistry, reading metadata through JobRepository/JobExplorer. So JobOperator complements — it doesn't replace — JobLauncher: launcher runs, operator manages the lifecycle around running jobs.

code

java · 16 lines
java
@Service
public class BatchOps {

    private final JobOperator jobOperator; // SimpleJobOperator

    public BatchOps(JobOperator jobOperator) {
        this.jobOperator = jobOperator;
    }

    // Operator-style: by name + Properties, returns execution id
    public Long importFile(String path) throws Exception {
        Properties p = new Properties();
        p.setProperty("inputFile", path);
        return jobOperator.start("importJob", p);
    }
}

go deeper

for a junior

Know it's the ops facade: start/stop/restart by name and id, vs JobLauncher which just runs a Job.

for a middle

Know SimpleJobOperator's four collaborators and that jobs are resolved by name from JobRegistry.

for a senior

Can explain when to reach for operator vs launcher and the String-vs-typed parameter nuance.

for a principal

Positions JobOperator as the boundary for external management tooling (JMX/CLI/console) and knows registry wiring pitfalls.

**The two abstractions.** Spring Batch separates *launching* a job from *operating* jobs. - `JobLauncher` is the minimal runner. Its only method is `JobExecution run(Job job, JobParameters jobParameters)`. You must already hold a `Job` bean and build a typed `JobParameters` object. The default `TaskExecutorJobLauncher` (formerly `SimpleJobLauncher`) runs it synchronously or, if given an async `TaskExecutor`, on another thread. - `JobOperator` is an operations/management facade. It is designed to be driven by things that don't have Java handles to your beans: a command-line launcher, a JMX MBean, an admin web page. Therefore every method speaks in *simple types* — `String` job names, `long` execution and instance ids, `java.util.Properties` for parameters. **Core methods (classic Spring Batch 5.x interface).** - `Long start(String jobName, Properties parameters)` — create and run a brand-new `JobInstance`. - `Long startNextInstance(String jobName)` — run the next instance using the job's `JobParametersIncrementer`. - `Long restart(long executionId)` — re-run a failed/stopped execution of the same instance. - `boolean stop(long executionId)` — request a graceful (cooperative) stop. - `JobExecution abandon(long executionId)` — mark a non-running execution as ABANDONED. - Query side: `Set<Long> getRunningExecutions(String jobName)`, `Set<String> getJobNames()`, `List<Long> getJobInstances(...)`, `getExecutions(long instanceId)`, `String getSummary(long executionId)`, `Map<Long,String> getStepExecutionSummaries(...)`, `String getParameters(long executionId)`. **Implementation and wiring.** The stock implementation is `SimpleJobOperator`. It needs four collaborators: a `JobLauncher` (to actually run), a `JobRegistry` (to resolve a `Job` from a `String` name), a `JobRepository`, and a `JobExplorer` (to read execution metadata). Because it resolves jobs by *name*, your `Job` beans must be registered in the `JobRegistry` — historically via a `JobRegistryBeanPostProcessor` (newer versions use a `JobRegistrySmartInitializingSingleton`). If the registry is empty, `start("myJob", ...)` fails with `NoSuchJobException`. **When to use which.** Use `JobLauncher` inside application code that already owns the `Job` (e.g. a `CommandLineRunner`, a scheduled method, an integration flow). Use `JobOperator` when a human operator or an external tool must manage jobs by name/id — cancel a runaway execution, kick off the next daily run, restart yesterday's failure, or list what's currently running. Note: parameters passed to `JobOperator.start` come in as `String`s (from `Properties`), so type-conversion of parameter values differs subtly from constructing `JobParameters` directly. **Version note.** The signatures above describe the long-stable Spring Batch 5.x `JobOperator`. Spring Batch has continued to evolve this facade in later major versions, but the operational concepts — start, startNextInstance, stop, restart, abandon, list running — are the constant interview target.

  • Which collaborators must a SimpleJobOperator be given?
    A JobLauncher (to run), a JobRegistry (to resolve Job by name), a JobRepository, and a JobExplorer (to read metadata). Missing/empty registry causes NoSuchJobException.
  • Why does JobOperator use Strings and longs instead of Job/JobParameters objects?
    So it can be driven by tools without Java references — JMX MBeans, CLI launchers, admin web consoles — which naturally pass job names and numeric ids.

saying these in an interview costs you the question

  • Saying JobOperator replaces JobLauncher (it delegates to one)
  • Thinking JobOperator takes a Job object rather than a job name
  • Not knowing it needs a JobRegistry to look jobs up by name

context

open as a page

Explain the difference between JobOperator.stop and JobOperator.abandon, including the semantics of a stop request.

level: seniorimportance: must knowfreq 48%

basics

~20 s

stop asks a running execution to halt gracefully — it sets the status to STOPPING and the job stops at the next safe point, ending STOPPED. abandon marks a non-running execution as ABANDONED so it's skipped on restart. stop is cooperative, not a kill.

open as a page

What does JobOperator.startNextInstance do, and what must the Job provide for it to work?

level: middleimportance: should knowfreq 45%

basics

~20 s

startNextInstance runs a new instance of a job automatically. It uses the job's JobParametersIncrementer to derive the next parameters from the previous run — for example bumping a run.id counter — so each call is a distinct JobInstance.

open as a page

How do getRunningExecutions and restart work in JobOperator, and how would you use them to safely manage a repeating job?

level: seniorimportance: should knowfreq 38%

basics

~20 s

getRunningExecutions(jobName) returns the ids of executions currently in flight for that job, so you can avoid launching overlapping runs. restart(executionId) re-runs a failed or stopped execution of the same instance, picking up per its restart semantics.

open as a page

In production, how would you wire up a JobOperator and expose it so operators can manage jobs (e.g., over JMX or an admin endpoint)? What are the pitfalls?

level: principalimportance: nice to knowfreq 28%

basics

~20 s

Define a SimpleJobOperator bean wired with JobLauncher, JobRegistry, JobRepository, and JobExplorer, and make sure every Job is registered in the JobRegistry so it can be found by name. Then expose the operator via a JMX MBean or a secured admin controller.

open as a page