java - 为 Tomcat 上的 Webapp 安排任务

标签 java tomcat quartz-scheduler

在我正在构建的自学网络应用程序中寻找处理计划任务的方法时,我看到了以下答案。 我正在使用随 Netbeans 安装的最新版本的 Quartz 和 Tomcat 8.0.27。

Simple example for Quartz 2.2 and Tomcat 7

XML-less

  • This requires Servet 3.0+ (Tomcat 7+, Glassfish 3+, JBoss AS 7)

You only need two files: TestJob.java from the previous example and the following listener:

由于我没有使用 Maven 并且不想使用 XML,我有一些与之相关的问题,因为我在运行代码启动 Tomcat 时遇到错误。

我尝试每十二小时在 08:30 和 20:30 运行一次任务

答案是不要

To avoid conflicts, do not set the default listener in the web.xml

但除非我在我的应用程序的 web xml 中设置监听器,否则它不会运行作业。

<listener> 
<listener-class>medsched.slisteners.MedSchedContextListener</listener-class> 
</listener>

应该是这种情况,还是我误解了这部分答案?

即使使用突出显示的答案的间隔,我得到的错误与 Tomcat 看到线程在不停地运行这一事实有关。 它报告以下内容

18-Nov-2017 15:46:20.347 WARNING [http-nio-8084-exec-3]  org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads 
The web application [medsched] appears to have started a thread named  [DefaultQuartzScheduler_Worker-10] but has failed to stop it. 
This is very likely to create a memory leak. Stack trace of thread:
 java.lang.Object.wait(Native Method)
 org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:568)

我应该添加额外的代码来防止错误吗?

public class MedSchedContextListener extends QuartzInitializerListener{
private final static Logger LOG = LogManager.getLogger(MedSchedContextListener.class);
@Override
public void contextInitialized(ServletContextEvent sce) {
    super.contextInitialized(sce);
    ServletContext ctx = sce.getServletContext();
    StdSchedulerFactory factory = (StdSchedulerFactory) ctx.getAttribute(QUARTZ_FACTORY_KEY);
    try {
        Scheduler scheduler = factory.getScheduler();
        JobDetail jobDetail = JobBuilder.newJob(MedSchedReminder.class).build();
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity("simple").withSchedule(
                CronScheduleBuilder.cronSchedule("0 30 8,20 1/1 * ? *")).startNow().build();
        scheduler.scheduleJob(jobDetail, trigger);
        scheduler.start();
    } catch (Exception e) {
        LOG.error("There was an error scheduling the job.", e);
    }
}

}

编辑的 web.xml 部分现在停止了错误。

<context-param>
     <param-name>quartz:shutdown-on-unload</param-name>
     <param-value>true</param-value>
 </context-param>
 <context-param>
     <param-name>quartz:wait-on-shutdown</param-name>
     <param-value>true</param-value>
 </context-param>

 <listener>
    <listener-class>medsched.slisteners.MedSchedContextListener</listener-class>
</listener>

最佳答案

根据 QuartzInitializerListener 的源代码,quartz 正在关闭,但 waitOnShutdown 标志设置为 false,因此 Tomcat 没有等待quartz 在它关闭之前完成,所以 Tomcat 决定它让线程运行并提示。

除了 shutdown-on-unload 属性之外,尝试在您的监听器配置中将 quartz:wait-on-shutdown 初始化为 true已经默认为 true (web.xml)。

 <context-param>
     <param-name>quartz:shutdown-on-unload</param-name>
     <param-value>true</param-value>
 </context-param>
 <context-param>
     <param-name>quartz:wait-on-shutdown</param-name>
     <param-value>true</param-value>
 </context-param>

关于java - 为 Tomcat 上的 Webapp 安排任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47368303/

相关文章:

使用 SNMP 监视 Java 应用程序

java - 如何确定正在使用的 oc4j 版本?

java - Apache Tomcat 配置问题

spring boot tomcat终止

java - Spring - 切换要使用的SchedulerFactoryBean

java - 使用 docker 和 logback 记录到文件

java - 元数据提取器 java 不提取 exif 或 iptc

java - java -Dnop 有什么作用?

java - 使用 Quartz 获取数据库连接

java - 如何每隔一小时定期删除 session 数据?