「[[ASP.NET/定期的にTaskを実行する]]」の内容を、[[QuizML>QuizML/WebService Provider実装]]に試験的に実装し、ASP.NETで非同期実行ができることがわかりました。じゃぁ、J2EEではどうなんだ? ということで、やってみました。
* java.util.TimerをServletで使う [#n9c0bc76]
+ まず、java.util.TimerTaskクラスを継承、runメソッドを実装したクラスを作成し、runメソッド内に実行したいタスクを記述します。
-- サンプルクラス &ref(Task01.java);
+ Servlet内でTimerインスタンスを生成し、上で作成したTaskを登録するだけです。
Timer timer1 = new Timer();
timer1.scheduleAtFixedRate(new Task01(config.getServletContext()), firstTime, peroid);
-- サンプルサーブレット &ref(TimerTestServlet01.java);
-- ※1 開始時刻として過去の時刻を設定すると、その時刻から現在時刻までの実行されたはずの回数分が、スケジュール登録時に一気に実行されてしまいます。開始時刻は、未来時刻になるようにするのが好いでしょうね。
- http://jomora.net/picture/ (18+)のサムネイル一覧とファイルシステムの同期を、毎日04:10に実行するように設定してみました。
- http://jomora.net/picture/ (18+) のサムネイル一覧とファイルシステムの同期を、毎日04:10に実行するように設定してみました。
*** 問題点 [#q4f83133]
- J2EEでjava.util.Timerを利用することは、問題があるようです。
++ J2EE 1.4仕様では、サーブレットのサービス・メソッド(service(), doPost(), doGet()等)から新たに別のスレッドを生成し、その新スレッドでJTA(Java Transaction API)を利用したトランザクションを開始することを禁じている
--- [[J2EE 1.4仕様:http://java.sun.com/j2ee/j2ee-1_4-fr-spec.pdf]]の「J2EE.4.2.3 Transactions and Threads」の節を参照
++ EJB 2.1仕様では、Enterprise Beanが開始、終了、中断、再開を含むスレッドの管理を行うことを禁じている。スレッドの管理はEJBコンテナの役割なのです。
--- [[EJB 2.1仕様:http://java.sun.com/products/ejb/docs.html]]の「25.1.2 Programming Restrictions」の節を参照
++ 開発者がクラスThreadのインスタンスを生成して新たなスレッドを開始した場合には、その新たなスレッドにJava EEコンテキストを渡すことができないため、そのスレッドは認証済みユーザーとは別のSecurity Identityを持つものとして稼働する可能性がある。また、トランザクションの開始や終了といった制御が行えない可能性がある。
- その解決策が、BEAとIBMが共同策定した「JSR 236:Timer for Application Servers」と「JSR 237:Work Manager for Application Servers」であり、その実行が「[[commonj:http://dev2dev.bea.com/wlplatform/commonj/twm.html]]」というプロジェクトらしい。
-- commonjはWebLogicとWebSphereで利用可能。オープン実装としては、[[Globus Toolkit:http://www.globus.org/toolkit/]]に含まれているものや、[[myFoo.de:http://www.myfoo.de/commonj/]]で配布されているものがある。
* [[Globus Toolkit:http://www.globus.org/toolkit/]]に含まれているcommonj実装 [#k610d1a4]
必要なパーツをうまく抽出できません ...orz
* [[myFoo.de:http://www.myfoo.de/commonj/]]で配布されているcommonj実装 [#l348a4cc]
Tomcat5.5を用い、<Context>(server.xml)およびweb.xmlで<Resource>設定をし、TimerManagerインスタンスの取得はできているようなのですが、java.lang.IllegalMonitorStateException が出まくります ...orz