All Products
Search
Document Center

SchedulerX:FAQ about Spring jobs

Last Updated:Mar 11, 2026

Why does the original Spring timer still run after SchedulerX takes over?

If a custom scheduler is specified in your application, SchedulerX overwrites the custom scheduler. This conflict typically occurs when a class implements org.springframework.scheduling.annotation.SchedulingConfigurer and calls the setScheduler method of ScheduledTaskRegistrar, which overwrites the default scheduler.

To resolve this issue:

  1. Search your project for any class that implements SchedulingConfigurer.

  2. Check whether the setScheduler method of ScheduledTaskRegistrar is called.

  3. If either condition is true, comment out the custom scheduler code.

How do I get the job context in a Spring job?

Call ContainerFactory.getContainerPool().getContext() to get the current JobContext:

// Get the SchedulerX job context inside a @Scheduled method
JobContext jobContext = ContainerFactory.getContainerPool().getContext();

Can a Spring job return a processing result?

This feature requires SchedulerX agent version later than 1.10.11. Versions 1.10.11 and earlier do not support return values from Spring jobs.

The processing results are returned based on the specified scheduling methods. Spring jobs support two return types:

Return typeUse case
ProcessResultReturn a success/failure status with a result message
StringReturn a result message only

Both examples below use the @Scheduled annotation with a cron expression.

Return a ProcessResult

Use ProcessResult to indicate success or failure along with a result message:

@Scheduled(cron = "0/5 * * * * ?")
public ProcessResult helloStandalone1() {
    try {
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. start");
        TimeUnit.SECONDS.sleep(2L);
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. end");
    } catch (Exception e) {
        e.printStackTrace();
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. exception end..");
    }
    // First argument: true for success, false for failure
    // Second argument: result message
    return new ProcessResult(true, "Processing result");
}

Return a String

Return a String directly when you do not need an explicit success/failure flag:

@Scheduled(cron = "0/5 * * * * ?")
public String helloStandalone2() {
    try {
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. start");
        TimeUnit.SECONDS.sleep(2L);
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. end");
    } catch (Exception e) {
        e.printStackTrace();
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. exception end..");
    }
    return "Processing result";
}