title: Handle WildFly component shutdown gracefully
body: <p>How do I implement a service inside a war-container deployed on wildfly that is able to gracefully shutdown? I have the following example code:</p>
  
  <p>SomeService.java:</p>
  
  <pre><code>@Stateless
  public class SomeService {
      public void doThing() {
          // this will fail once the component is shut down.
          System.out.println("Doing some work...");
      }
  }
  </code></pre>
  
  <p>SomeWorker.java:</p>
  
  <pre><code>@Singleton
  @Startup
  public class SomeWorker {
  
      @Inject
      private SomeService service;
  
      @Resource
      private TimerService timerService;
  
      @PostConstruct
      public void doWork() {
          System.out.println("Started startup bean...");
          timerService.createSingleActionTimer(10, new TimerConfig());
      }
  
      @Timeout
      public void doLater() {
          while (!Thread.interrupted()) {
              service.doThing();
              try {
                  Thread.sleep(1000);
              } catch (InterruptedException e) {
                  Thread.currentThread().interrupt();
              }
          }
          System.out.println("graceful shutdown");
      }
  }
  </code></pre>
  
  <p>This code simply starts calling an EJB's method in a loop. If this were a pure Java SE application (replacing the EJB annotations with respective replacements), simply catching the <code>InterruptedException</code> is sufficient for regular graceful shutdowns (not killing the VM with <code>kill -9</code>, but that's out of scope for me anyway).</p>
  
  <p>However in this scenario I don't know how I would detect the module being undeployed. If I undeploy the war-file (in my case by renaming the <code>test.war.deployed</code> file to <code>test.war.undeployed</code>), it simply starts eventually throwing <code>ComponentIsStoppedException</code> on EJB accesses:</p>
  
  <pre><code>14:14:17,250 INFO  [stdout] (EJB default - 1) Doing some work...
  14:14:18,252 INFO  [stdout] (EJB default - 1) Doing some work...
  14:14:19,253 INFO  [stdout] (EJB default - 1) Doing some work...
  14:14:19,808 INFO  [org.jboss.as.server.deployment.scanner] (DeploymentScanner-threads - 2) WFLYDS0033: Deployment test.war was previously undeployed by this scanner but has been redeployed by another management tool. Marker file D:\&lt;path&gt;\wildfly\standalone\deployments\test.war.undeployed is being removed to record this fact.
  14:14:19,831 INFO  [org.wildfly.extension.undertow] (ServerService Thread Pool -- 67) WFLYUT0022: Unregistered web context: '/test' from server 'default-server'
  14:14:20,256 ERROR [org.jboss.as.ejb3.timer] (EJB default - 1) WFLYEJB0020: Error invoking timeout for timer: [id=4de4a666-5a6e-4830-aa89-21d2040d04f0 timedObjectId=test.test.SomeWorker auto-timer?:false persistent?:true timerService=org.jboss.as.ejb3.timerservice.TimerServiceImpl@526b0669 initialExpiration=Thu Oct 18 14:14:09 CEST 2018 intervalDuration(in milli sec)=0 nextExpiration=null timerState=IN_TIMEOUT info=null]: javax.ejb.EJBException: org.jboss.as.ee.component.ComponentIsStoppedException: WFLYEE0043: Component is stopped
          ...
  Caused by: org.jboss.as.ee.component.ComponentIsStoppedException: WFLYEE0043: Component is stopped
          at org.jboss.as.ee.component.BasicComponent.waitForComponentStart(BasicComponent.java:110)
          at org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:194)
          at org.jboss.as.ee.component.ViewDescription$1.processInvocation(ViewDescription.java:185)
          at org.jboss.as.ee.component.ProxyInvocationHandler.invoke(ProxyInvocationHandler.java:81)
          at test.SomeService$$$view1.doThing(Unknown Source)
          ...
          at test.SomeService$Proxy$_$$_Weld$EnterpriseProxy$.doThing(Unknown Source)
          at test.SomeWorker.doLater(SomeWorker.java:31)
          ...
  </code></pre>