繁体   English   中英

ServletContextListener调度程序执行任务-然后暂停EJB方法调用以将其持久保存到JBOSS 7.1中的数据库中

[英]ServletContextListener scheduler carry out a task - then stalls on EJB method call to persist into a database in JBOSS 7.1

我有一个ServletContextListener,它每20秒运行一次任务-该任务是侦听文件夹并检查是否有新文件,如果找到,则将新文件导入数据库。 这是使用以下问题给出的答案设置的: 使用计时器在JSF托管Bean中生成线程以执行计划的任务

ServletContextListener的Java代码

@WebListener
public class Listener implements ServletContextListener {

     private ScheduledExecutorService scheduler;

        @Override
        public void contextInitialized(ServletContextEvent event) {
            scheduler = Executors.newSingleThreadScheduledExecutor();

            scheduler.scheduleAtFixedRate(new MyTask(), 0,20, TimeUnit.SECONDS);
        }

        @Override
        public void contextDestroyed(ServletContextEvent event) {
            scheduler.shutdownNow();
            System.out.println("Terminating the Listener");
        }
}

MyTask的Java代码

public class MyTask implements Runnable{

@EJB
LoaderManager loaderManager;

@Schedule(hour="0", minute="0", second="0", persistent=false)
public void run() {

                //Some unnecessary code left out


        if (itIsOkToImportTheDatabase)
            {


            loaderManager.loadDatabase(pathToNewFile);


            if (thisistrue) {
                //doesnt matter
            } else {
                //doesnt matter
            }
        }

        else

        {
            // not important
            }
        }
    }

}

Java Code for LocalBean通过JPA将数据导入数据库

@Stateless
@LocalBean
public class LoaderManager implements LoaderManagerDAO{

    @Inject
    private EntityManager em;
    private Row row = null;
    private FileInputStream inp;
    private Workbook wb;

    public void loadDatabase(String FileLocation) {

        InputStream inp = null;

// some file set up stuff, using Apache POI

Sheet sheet1 = wb.getSheetAt(0);

for (int i = 1; i <= sheet1.getLastRowNum(); i++) {
            // loop through each row

            em.persist(elementsInRow);

        }

侦听器确实检查了文件夹-但是调用导入数据库的代码时-似乎停滞了,在JBOSS控制台上没有出现错误。 我试图以多种方式注入LoaderManager,但遇到了麻烦...该方法调用loaderManager.loadDatabase(pathToNewFile); 除非我使用实例化它不会达到LoaderManager类(与打印语句检查)

LoaderManager loaderManager = new LoaderManager():

..我非常确定这是错误的,即使它只能达到(但不执行,通过print语句检查)

em.persist(elementsInRow);

WebApp的所有其他功能似乎均未受此影响,任何帮助/建议将不胜感激,

干杯。

您的代码毫无意义。 注入是错误的,在Java EE环境中,使用非托管线程通常不是一个好主意。 由于您将容器与Java EE 6一起使用,请考虑使用单例启动bean和timerservice:

   @Startup
   @Singleton
   public class SchedulerBean {
     @Resource
     private TimerService timerService;
     @EJB
     private LoaderManager loaderManager;
     private Timer timer;

     @PostConstruct
     public void init() {
       timer = timerService.createIntervalTimer(20 * 1000, 20 * 1000, new TimerConfig(null, false));
     }

     @PreDestroy
     public void deinit() {
       timer.cancel();
     }

     @Timeout
     public void schedule(Timer timer) {
        // TODO: Add your checks here
        loaderManager.loadDatabase(databaseLocation);
     }
   }

另外,我认为您应该为LoaderManager使用单例bean而不是无状态bean。

您将在以下行中实例化MyTask

scheduler.scheduleAtFixedRate(new MyTask(), 0,20, TimeUnit.SECONDS);

哪个利用

@EJB
LoaderManager loaderManager;

它将由EJB容器注入。 这样很可能无法正常工作。

实现此目的的一种方法是通过为MyTask构造一个构造器来执行以下操作

public MyTask() {
    try {
        InitialContext ctx = new InitialContext();

        loaderManager = (LoaderManager) ctx.lookup("<Package Name>.LoaderManager");

    } catch (NamingException ex) {
        // Error Handling
    }
}

在这种情况下,如果LoaderManager作为远程客户端公开给其他应用程序,则您应该可以将其取回。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM