Skip to content
Advertisement

RejectedExecutionException in ScheduledFutureTask in Spring WebApp after ContextRefreshed

I’m using this code to Schedule a Task in my Java 8 Spring WebApp:

In a @Controller;

@EventListener(ContextRefreshedEvent.class)
public void doSomethingAfterContextRefreshed() {

    ScheduledFuture<?> countdown = scheduler.schedule(new Runnable() {
        @Override
        public void run() {

            try {
                Execute();
            } catch (IOException e) {
                e.printStackTrace();
            }
         
        }}, 10, TimeUnit.SECONDS);

    while (!countdown.isDone()) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    scheduler.shutdown();
}

When the App starts, the Execute() method gets called 10 seconds after startup with no errors, but after it completes I get the following stack trace:

java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@52518e6[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@759546c8[Wrapped task = com.mycompany.myproject.service.LoadService$1@4871ba3f]] rejected from java.util.concurrent.ScheduledThreadPoolExecutor@798daafa[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 1] at java.base/java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2055) at java.base/java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:825) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:340) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:562)

Any ideas why I get this exception?

Advertisement

Answer

Let’s simplify this:

public class DeleteMe {

    public static void main(String[] args) {
        doSomethingAfterContextRefreshed();
        doSomethingAfterContextRefreshed();
    }

    static ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(1);

    public static void doSomethingAfterContextRefreshed() {

        ScheduledFuture<?> countdown = scheduler.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("Some message");
            }}, 100, TimeUnit.MILLISECONDS);

        while (!countdown.isDone()) {
            LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(10));
        }
        scheduler.shutdown();
    }

}

At the end of the first invocation of doSomethingAfterContextRefreshed – what do you do? scheduler.shutdown();.

At the second invocation of doSomethingAfterContextRefreshed(); what do you do? scheduler.schedule(....).

Is the scheduler shutdown at this point in time? What does the documentation of schedule says to throw in such cases? You have your answer now.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement