title: EJB and WatchService
body: <p>I developp an application on a JBoss 7.1 which have to monitor a directory of the fileSystem.
  For this purpose, I write some code which looks like what I found in this post :<a href="https://stackoverflow.com/questions/14381274/ejb-3-1-and-nio2-monitoring-the-file-system">EJB 3.1 and NIO2: Monitoring the file system</a>.
  So I write a session ejb PollingServiceImpl with an asynchronous method watching the path I have to monitor and an @StartUp Ejb which call the session EJB. 
  Here is my code for the PollingService :</p>
  
  <pre><code>@Stateless
  public class PollingServiceImpl {
  private Path       fichiersXmlPath=Paths.get("/media/sf_DossierPartage/IsidoreJaxb/specXML/fichiersXml");
  
  /**
   * Default constructor. 
   */
  public PollingServiceImpl() {
      // TODO Auto-generated constructor stub
  }
  
  
  @Asynchronous
  public void pollForXmlMessage()  {
  
       WatchService service=null;
      // Vérification que le path est un répertoire
      try {
          Boolean isFolder = (Boolean) Files.getAttribute(fichiersXmlPath,
                  "basic:isDirectory", LinkOption.NOFOLLOW_LINKS);
          if (!isFolder) {
              throw new IllegalArgumentException("le path : " + fichiersXmlPath + " n'est pas un répertoire");
          }
      } catch (IOException ioe) {
          System.out.println("le path : " + fichiersXmlPath + " n'est pas un répertoire");
  
      }
  
      System.out.println("Répertoire observé: " + fichiersXmlPath);
  
      // On obtient le système de fichier du chemin
      FileSystem fs = fichiersXmlPath.getFileSystem ();
  
      // We create the new WatchService using the new try() block
      try{ service = fs.newWatchService();
  
          //On enregistre le chemin dans le watcher
          // On surveille les opérations de création
          fichiersXmlPath.register(service, StandardWatchEventKinds.ENTRY_CREATE);
  
          // Beginning of the infinite loop
  
          for(;;) {
              WatchKey key = service.take();
  
              // Sortir les événements de la queue
              Kind&lt;?&gt; kind = null;
              for(WatchEvent&lt;?&gt; watchEvent : key.pollEvents()) {
                  // on teste le type de l'événement
                  kind = watchEvent.kind();
  
                  // If les événements sont perdus
                  if (StandardWatchEventKinds.OVERFLOW == kind) {
                      continue; //loop
  
                  // Si c'est un événement de création
                  } else if (StandardWatchEventKinds.ENTRY_CREATE == kind) {
                      // A new Path was created 
                      Path newPath = ((WatchEvent&lt;Path&gt;) watchEvent).context();
                      // Output
                      System.out.println("nouveau chemin : " + newPath +" numKey "+key.toString() );
  
                      // buisness process
                  }
              }
  
              if (key != null) {
                  boolean valid = key.reset();
                  if (!valid) break; // If the key is no longer valid, the directory is inaccessible so exit the loop.
              }
  
          }
  
      } catch(IOException ioe) {
          ioe.printStackTrace();
      } catch(InterruptedException ie) {
          ie.printStackTrace();
      } finally{
          try {
              service.close();
          } catch (IOException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
      }
  
  }
  
  
  }
  </code></pre>
  
  <p>and here is the code for the startp ejb :
      @Singleton
  @Startup
  public class Initialiser {</p>
  
  <pre><code>        @EJB
          private PollingServiceImpl pollingService;
  
          public enum States {BEFORESTARTED, STARTED, PAUSED, SHUTTINGDOWN};
  
          private States state;
  
  
          @PostConstruct
          public void initialize() {
  
          state = States.BEFORESTARTED;
  
         pollingService.pollForXmlMessage();
           state = States.STARTED;
           System.out.println("ETAT : "+state.toString());
          }
  
  
          @PreDestroy
          public void terminate() {
  
          state = States.SHUTTINGDOWN;
  
          System.out.println("Shut down in progress");
  
          }
  
          public States getState() {
  
          return state;
  
          }
  
          public void setState(States state) {
  
          this.state = state;
  
          }
  
      }
  </code></pre>
  
  <p>Everything looks fine and the watcher works well but I have two problems :
  1) Some warnings appears on the console like this :
      [com.arjuna.ats.arjuna] (Transaction Reaper Worker 0) ARJUNA012095: Abort of action id
      0:ffff7f000101:-51121f7e:53b7f879:9 invoked while multiple threads active within it.
      15:12:14,522 WARN  [com.arjuna.ats.arjuna] (Transaction Reaper Worker 0) ARJUNA012108:<br>
      CheckedAction::check - atomic action 0:ffff7f000101:-51121f7e:53b7f879:9 aborting with<br>
      1 threads active!
      15:12:14,522 WARN  [com.arjuna.ats.arjuna] (Transaction Reaper Worker 0) ARJUNA012121: 
      TransactionReaper::doCancellations worker Thread[Transaction Reaper Worker 0,5,main] 
      successfully canceled TX 0:ffff7f000101:-51121f7e:53b7f879:9   </p>
  
  <p>2) The server refuse to shutdown : apparently the thread launched at start up don't stop. I have read in some posts that i have to stop the method pollForXmlMessage in the @PreDestroy method of the Initializer ejb but I don't know how i can make that or if there is another solution.</p>
  
  <p>Can someone help me please? </p>