Fernando Blanch
Fernando Blanch

Reputation: 131

Spring Batch and non-daemon threads

If there is a non-daemon thread in a Spring Batch application, when the Batch terminates the application never shutsdown, i.e. the shutdown signal never reaches the JVM.

Is this expected behaviour, or does Spring Batch fail to send the signal due to a malfunction?

I attach a very simple application that reproduces the case: https://github.com/ferblaca/SpringBatchDemo

Versions: Spring boot 2.4.5 Spring Batch 4.3.2 Java 11

Upvotes: 0

Views: 691

Answers (1)

Mahmoud Ben Hassine
Mahmoud Ben Hassine

Reputation: 31600

This is not related to Spring Batch. Spring Batch does not prevent your JVM from shutting down. As soon as your job is finished, your JVM should terminate, otherwise there is something else preventing it from shutting down. In your case, it is your executor service that you've configured as non-daemon thread.

I took your example and removed everything related to Spring Batch, and the same thing happens:

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;

import org.apache.commons.lang3.concurrent.BasicThreadFactory;

import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

@SpringBootApplication
public class DemoBatchApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder().sources(com.example.demo.batch.DemoBatchApplication.class)
            .web(WebApplicationType.NONE)
            .run(args);
    }

    private final ScheduledExecutorService scheduledExecutorService = Executors
            .newSingleThreadScheduledExecutor(new BasicThreadFactory.Builder()
                    .namingPattern("task-non-daemon-%d")
                    .daemon(false)
                    .build());

    @PostConstruct
    public void init() {
        this.scheduledExecutorService.scheduleAtFixedRate(() -> {
            System.out.println("Scheduled task non-daemon!!!!");
        }, 1L, 1000L, TimeUnit.MILLISECONDS);
    }
    
}

If you run this app, you should see the same behaviour: the scheduledExecutorService will keep running since you set it as a non-daemon thread. If you change the daemon flag to true, the JVM will stop as soon as your job is finished. Please check What is a daemon thread in Java?.

Upvotes: 1

Related Questions