我有一个简单的应用程序,它具有一个从Servlet侦听器启动的Quartz调度程序。该代码可在https://github.com/ike3/quartz-and-ejb
上找到唯一有趣的部分是该作业调用了一个远程EJB:
InitialContext initialContext = new InitialContext();
PpaJobRemote remote = (PpaJobRemote) initialContext.lookup(beanName);
remote.process();
该代码打包为包含EJB-JAR和WAR的EAR,然后部署在WildFly 18应用程序服务器上。可以确定的是:EAR / lib和WEB-INF / lib中没有重复的接口。
一切正常,直到重新启动模块。然后突然查找失败,并出现以下异常:
Caused by: javax.ejb.NoSuchEJBException: EJBCLIENT000079: Unable to discover destination
for request for EJB StatelessEJBLocator for "fz44-test-jobs-ear/fz44-test-jobs-ejb/SendMailMessageJob",
view is interface ru.lanit.fz44.ejb.job.PpaJobRemote, affinity is None
仅从Quartz作业发生问题。我有Servlet在相同的WAR中调用相同的作业-在重新启动后它可以正常工作。因此,我认为Quartz线程池和Widlfly类加载器之间存在一些怪异的错误。
如果我重新启动整个服务器(而不是单个模块),则错误消失了。问题在于,CI服务器中的部署脚本使用jboss CLI会不时有效地重新启动模块,这更糟。
有人可以建议解决此问题的任何方法吗?
似乎我知道了。问题是我没有关闭调度程序。显然,即使重新启动应用程序,Quartz仍会重用同一调度程序。
将其添加到servlet侦听器中解决了该问题。
public void contextDestroyed(ServletContextEvent event) {
try {
if (sched.isStarted()) {
sched.shutdown();
}
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
另一个示例,所有资源在使用后都必须关闭,而忘记这样做可能会导致奇怪的问题。