首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >EJB和WatchService

EJB和WatchService
EN

Stack Overflow用户
提问于 2014-07-05 21:35:11
回答 2查看 2.2K关注 0票数 0

我在JBoss 7.1上开发了一个应用程序,它必须监视fileSystem的一个目录。为此,我编写了一些代码,与我在这篇文章中找到的代码类似:EJB 3.1 and NIO2: Monitoring the file system。因此,我编写了一个带有异步方法的会话EJB,监视我必须监视的路径,以及一个调用会话PollingServiceImpl的@StartUp ejb。下面是我的PollingService代码:

代码语言:javascript
复制
@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<?> kind = null;
            for(WatchEvent<?> 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<Path>) 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();
        }
    }

}


}

下面是startp ejb的代码:@Singleton @Startup public class Initialiser {

代码语言:javascript
复制
        @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;

        }

    }

一切看起来都很好,观察器运行良好,但是我有两个问题: 1)一些警告出现在控制台上,如下所示:com.arjuna.ats.arjuna ARJUNA012095: Abort of action id 0:ffff7f000101:-51121f7e:53b7f879:9当其中有多个线程处于活动状态时被调用。15:12:14,522警告com.arjuna.ats.arjuna ARJUNA012108:

代码语言:javascript
复制
 CheckedAction::check - atomic action 0:ffff7f000101:-51121f7e:53b7f879:9 aborting with
代码语言:javascript
复制
 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   

2)服务器拒绝关闭:显然在启动时启动的线程不会停止。我在一些文章中读到,我必须在Initializer ejb的@PreDestroy方法中停止方法pollForXmlMessage,但我不知道如何才能做到这一点,或者是否有其他解决方案。

有人能帮帮我吗?

EN

回答 2

Stack Overflow用户

发布于 2015-04-07 14:29:09

以下是解决方案的模板:

代码语言:javascript
复制
public class Service{
    private volotile boolean isCancelled = false;

    public void startService()
    {   //infinit loop:
        while(!isCancelled) {}
    }

    public void stopService()
    {
        isCancelled = true;
    }
}
@Singleton
@Startup
public class ServiceStarter{

    Service service;
    @EJB ServiceAsyncWorker asyncWorker;

    @PostConstruct
    private void init()
    {
        service = new Service(...);
        asyncWorker.startService(service);
    }

    @PreDestroy
    private void destroy()
    {
        service.stopService();
    }
}
@Singleton
public class ServiceAsyncWorker{
    @Asynchronous
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public void startService(Service service){
        service.startService();
    }
}
票数 2
EN

Stack Overflow用户

发布于 2014-07-06 06:02:42

每个EJB方法都在事务上下文中执行。如果您的方法从未返回,JBoss会通知您可能挂起了一个非常长的事务。

相反,我建议将其移动到资源适配器中,该适配器在新文件等事件上调用MDB。http://robertpanzer.github.io/blog/2014/inboundra-nointfmdbs.html显示了一个使用JavaEE7风格的MDB的示例,但是将其向下移植到JavaEE 6和JBoss 7应该是微不足道的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24586957

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档