[英]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.