Java EE Server 上寫一個排程工作,只要加一個 @Schedule 就可以了,Tomcat 除了用 Java SE 的 TimerTask 來排程外的另一個選擇就是 quartz,看了一下有支援 Thread Pool,設定檔不用寫在程式碼上,之後要寫 ant 來置換比較方便,就決定用 quartz。
使用版本
Tomcat7 + quartz 2.1.7步驟
http://www.quartz-scheduler.org/documentation/quartz-2.1.x/quick-start 是一個官網的簡單使用說明,下面是我自己使用的筆記。1) 安裝
到官網下載,解壓縮後 lib 下的 jar 檔都加入專案的 build path。2) 啟用 quartz
web.xml 加入 QuartzInitializerListener,QuartzInitializerListener 實作了 javax.servlet.ServletContextListener,QuartzInitializerListener 在 Web App 啟動後就會初始化 quartz 相關的設定。WebContent/WEB-INF/web.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<servlet> | |
<servlet-name>QuartzInitializer</servlet-name> | |
<servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class> | |
<init-param> | |
<param-name>shutdown-on-unload</param-name> | |
<param-value>true</param-value> | |
</init-param> | |
<init-param> | |
<param-name>wait-on-shutdown</param-name> | |
<param-value>true</param-value> | |
</init-param> | |
<init-param> | |
<param-name>start-scheduler-on-load</param-name> | |
<param-value>true</param-value> | |
</init-param> | |
<load-on-startup>1</load-on-startup> | |
</servlet> |
3) 設定 quartz
WebContent/WEB-INF/classes/quartz.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
org.quartz.threadPool.threadCount=2 # 用2個 Thread | |
org.quartz.plugin.jobInitializer.class=org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin # 用 XML(quartz_data.xml) 設定排程工作 |
4) 設定排程工作
quartz_data.xml 內,- 建立一個 Job,取名並指定實作類別。
- 建立一個 Trigger,取名,指定 Job 和執行時間。
WebContent/WEB-INF/classes/quartz_data.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<job-scheduling-data | |
xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData http://www.quartz-scheduler.org/xml/job_scheduling_data_2_0.xsd" | |
version="1.8"> | |
<schedule> | |
<job> | |
<name>FooJob</name> | |
<job-class>com.tangblack.quartz.example.FooJob</job-class> | |
</job> | |
<!-- cron-expression: Seconds Minutes Hours DayOfMonth Month DayOfWeek Year --> | |
<trigger> | |
<cron> | |
<name>FileJobTrigger</name> | |
<job-name>FooJob</job-name> | |
<cron-expression>0 0/1 * * * ? *</cron-expression> | |
</cron> | |
</trigger> | |
</schedule> | |
</job-scheduling-data> |
5) 實作排程工作
FooJob.java
public class FooJob implements Job
{
@Override
public void execute(final JobExecutionContext ctx) throws JobExecutionException
{
// To something here!
}
}
問題
1) 執行時發生 java.lang.NoClassDefFoundError: javax/transaction/UserTransaction
嚴重: Exception sending context initialized event to listener instance of class org.quartz.ee.servlet.QuartzInitializerListener
java.lang.NoClassDefFoundError: javax/transaction/UserTransaction
下載 jta-1.1.jar 後,加入專案的 build path。
2) Tomcat7 關閉 Web App 出現 memory leak 警告。
[DefaultQuartzScheduler_Worker-5] but has failed to stop it. This is very likely to create a memory leak
這是因為 Tomcat7 關閉 Web App 時,沒有正確關閉 quartz 的關係,在QuartzInitializerListener 加入下列初始參數。
WebContent/WEB-INF/web.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<servlet> | |
<servlet-name>QuartzInitializer</servlet-name> | |
<servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class> | |
<init-param> | |
<param-name>shutdown-on-unload</param-name> | |
<param-value>true</param-value> | |
</init-param> | |
<init-param> | |
<param-name>wait-on-shutdown</param-name> | |
<param-value>true</param-value> | |
</init-param> | |
<init-param> | |
<param-name>start-scheduler-on-load</param-name> | |
<param-value>true</param-value> | |
</init-param> | |
<load-on-startup>1</load-on-startup> | |
</servlet> |