title: Bean lifecycle in Spring Boot 2.1 and Java 11
body: <p>My project is moving from Spring Boot 2.0.4 with Java 8 to Spring Boot 2.1.0 with Java 11. When the application was built with Spring Boot 2.0.4 and Java 8 and run in Docker / Docker Compose, the <code>@PostConstruct</code>-annotated method was called, but after the move to Spring Boot 2.1.0 and Java 11 the <code>@PreDestroy</code>-annotated method is no longer called.</p>
  
  <p>I have tried switching from annotations to implementing <code>InitializingBean</code> and <code>DisposableBean</code> as described <a href="https://better-coding.com/spring-postconstruct-and-predestroy-alternatives-in-java-9/" rel="nofollow noreferrer">here</a>, but the <code>DisposableBean.destroy</code> method is not called.</p>
  
  <p>I have also tried adding a dependency to javax.annotation-api version 1.3.2, with the same result.</p>
  
  <p>How to reproduce:</p>
  
  <p>Create a minimal Spring application with a lifecycle bean:</p>
  
  <pre><code>import org.springframework.beans.factory.DisposableBean;
  import org.springframework.beans.factory.InitializingBean;
  import org.springframework.stereotype.Component;
  
  @Component
  public class Life implements InitializingBean, DisposableBean {
      @Override
      public void destroy() throws Exception {
          System.out.println("--- Life.shutdown");
      }
      @Override
      public void afterPropertiesSet() throws Exception {
          System.out.println("--- Life.startup");
      }
  }
  </code></pre>
  
  <p>Start the Spring application from the target subfolder:</p>
  
  <pre><code>cd target
  java -jar demo-0.0.1-SNAPSHOT.jar
  </code></pre>
  
  <p>When the application is stopped using Ctrl+C, the DisposableBean.destroy is called.</p>
  
  <p>Return to the parent folder:</p>
  
  <pre><code>cd ..
  </code></pre>
  
  <p>Start the Spring application using Maven:</p>
  
  <pre><code>mvn spring-boot:run
  </code></pre>
  
  <p>When the application is stopped using Ctrl+C, the DisposableBean.destroy is called.</p>
  
  <p>Dockerfile:</p>
  
  <pre><code>FROM openjdk:11.0.1-jre-slim
  COPY target/*.jar app.jar
  EXPOSE 8080
  ENTRYPOINT java -jar /app.jar
  </code></pre>
  
  <p>Build, run, and stop Docker image:</p>
  
  <pre><code>docker build -t demo .
  docker run -p 8080:8080 demo
  docker ps
  docker stats 3ca5b804ab13
  docker stop 3ca5b804ab13
  docker logs 3ca5b804ab13
  </code></pre>
  
  <p>When the application is stopped using docker stop, the DisposableBean.destroy is not called.</p>
  
  <p>docker-compose.yml:</p>
  
  <pre><code>demo:
    image: demo
    ports:
    - '8080:8080'
  </code></pre>
  
  <p>Run Docker image using Docker Compose (simulating OpenShift):</p>
  
  <pre><code>docker-compose up
  docker-compose down
  demo_demo_1 exited with code 137
  </code></pre>
  
  <p>When the application is stopped using docker-compose down, the DisposableBean.destroy is not called.</p>
  
  <p>I suspect that Docker is trying a SIGTERM before it issues a SIGKILL, because there is a 10-second delay before the container is killed.</p>