Fusion Middleware Oracle WebLogic Server Timer and Work Manager API (CommonJ) プログラマーズ・ガイド

11g リリース1 (10.3.6)

B61632-04(原本部品番号:E13733-05)

Oracle® Fusion Middleware

Oracle WebLogic Server Timer and Work Manager API (CommonJ) プログラマーズ・ガイド

11g リリース1 (10.3.6)

B61632-04(原本部品番号:E13733-05)

2011年11月

この節では、Timer and Work Manager APIの概要を説明し、これらをアプリケーション内に実装する方法を示します。

- Timer and Work Manager APIとは

- Timer APIの概要

- Timer APIの使用

- ジョブ・スケジューラの使用

- Work Manager APIとは

- ワーク・マネージャのサンプル

Timer and Work Manager APIとは

Timer and Work Manager APIは、OracleとIBMが共同作成した仕様で定義されています。このAPIを使用すると、Java EEアプリケーション内にEJBとサーブレットを同時にプログラミングできます。このAPIはしばしばCommonJと呼ばれます。

CommonJ APIには、次のコンポーネントが含まれます。

- Timer API
Timer APIを使用すると、アプリケーション内に定義された特定のリスナーに対し、アプリケーションでタイマー通知コールバックをスケジューリングして受信できます。タイマー機能を利用すると、特定の時刻または間隔において作業するようにスケジューリングおよび実行することが可能です。「Timer APIの概要」を参照してください。

このAPIは、commonj.timerパッケージをインポートして実装します。

- Work Manager API
Work Manager APIを使用すると、アプリケーションでEJBまたはサーブレット内の作業の優先順位を決められます。アプリケーションは、複数の作業項目をコンテナ内部でプログラム的に実行できます。「Work Manager APIとは」を参照してください。

このAPIは、commonj.workパッケージをインポートして実装します。

WebLogic Serverには、CommonJ Work Manager API以外にもサーバー・レベルのワーク・マネージャが複数あり、優先順位の決定やスレッド管理を行えます。これらは、グローバルに構成することも、アプリケーションの特定のモジュール用に構成することも可能です。

commonj.timerとcommonj.workは同じAPIの一部ですが、それぞれ別の機能を提供します。どちらを実装するかは、アプリケーション固有のニーズによって決まります。CommonJ Timer APIは、作業を特定の間隔でスケジューリングする場合に理想的です。たとえば、あるジョブを特定の時刻に実行する必要がある場合などです。CommonJ Work APIは、作業を優先順位に基づいて処理する場合に理想的です。たとえば、特定のジョブの発生時期をはっきりと予測できないが、発生した場合には高い(または低い)優先順位を与える場合などです。

以下の節では、CommonJ APIを詳細に説明します。

Timer APIの概要

Timer APIは次の3つのインタフェースで構成されています。

- TimerManager

- TimerListener

- タイマー・オブジェクト

TimerManagerは、管理対象の環境においてタイマーを作成および使用するためのフレームワークを提供します。TimerListenerは、タイマー通知を受信します。TimerManager.schedule()メソッドを使用して、TimerListenerを特定の時刻または間隔において実行するようにスケジューリングします。

タイマーの実装方法の詳細は、「Timer APIの使用」を参照してください。

TimerManagerインタフェース

TimerManagerインタフェースは、アプリケーション内の全般的なスケジューリング・フレームワークを提供します。管理対象の環境では、複数のTimerManagerインスタンスをサポートできます。1つのアプリケーション内に複数のTimerManagerインスタンスを設定できます。

タイマー・マネージャの作成および構成

TimerManagerは、デプロイ中にデプロイメント記述子で構成されます。TimerManagerの定義には、実装固有の付加的な構成情報が含まれることもあります。

デプロイメント記述子にTimerManagerが定義されると、そのインスタンスはローカルJava環境でJNDIルックアップを使用してアクセスできるようになります。JNDI lookup()でTimerManagerを呼び出すたびに、TimerManagerの新しい論理インスタンスが返されます。

TimerManagerインタフェースはスレッドセーフです。

JNDIの仕様の詳細は、『Oracle WebLogic Server JNDIのプログラミング』を参照してください。

TimerManagerの中断

TimerManagerは、suspend()メソッドおよびresume()メソッドを使用して中断および再開できます。TimerManagerを中断すると、未処理のタイマーはすべてTimerManagerが再開されるまで保留されます。

TimerManagerの停止

TimerManagerは、stop()メソッドを使用すると停止できます。stop()が呼び出されると、アクティブなタイマーはすべて停止され、TimerManagerインスタンスはすべてのTimerListenerインスタンスのモニターを停止します。

TimerListenerインタフェース

commonj.timersパッケージを使用するすべてのアプリケーションは、TimerListenerインタフェースを実装する必要があります。

Timerインタフェース

Timerインタフェースのインスタンスは、TimerManagerを介してタイマーがスケジューリングされたときに返されます。

Timer APIの使用

この節では、アプリケーション内でTimer APIを使用するために必要な手順を簡単に示します。

アプリケーションをデプロイする前に、タイマー・マネージャへのリソース参照を含むデプロイメント記述子が作成済みであることを確認してください。

これにより、TimerManagerがJNDIを介してアクセス可能になります。JNDIルックアップの詳細は、『Oracle WebLogic Server JNDIのプログラミング』を参照してください。

Timer APIの実装

以下の手順で、Timer APIの実装方法を説明します。

1. commonj.timers.*パッケージをインポートします。

2. InitialContextを作成します。これによりTimerManagerがJNDIでルックアップ可能になります。

InitialContext inctxt = new InitialContext();

JNDIルックアップの詳細は、『Oracle WebLogic Server JNDIのプログラミング』を参照してください。

3. TimerManagerのJNDIルックアップに基づいて新しいTimerManagerを作成します。

TimerManager mgr = (TimerManager)ctx.lookup('java:comp/env/timer/MyTimer');

この文ではJNDIルックアップの結果がTimerManagerにキャストされています。

4. タイマー通知を受信するためにTimerListenerを実装します。

TimerListener listener = new StockQuoteTimerListener('abc', 'example');

5. TimerManager.schedule()を呼び出します。

mgr.schedule(listener, 0, 1000*60)

schedule()メソッドはTimerオブジェクトを返します。

6. timerExpired()メソッドを実装します。

public void timerExpired(Timer timer) {
//Business logic is executed
//in this method
}

クラスタ全体タイマーのTimer APIの実装では、要件が追加されます(「タイマーのライフ・サイクル」を参照)。

タイマー・マネージャのサンプル

package examples.servlets;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import commonj.timers.*;

/**
* TimerServlet demonstrates a simple use of commonj timers
*/
public class TimerServlet extends HttpServlet {

/**
* A very simple implementation of the service method,
* which schedules a commonj timer.
*/
public void service(HttpServletRequest req, HttpServletResponse res)
throws IOException
{
res.setContentType("text/html");
PrintWriter out = res.getWriter();
try {
InitialContext ic = new InitialContext();
TimerManager tm = (TimerManager)ic.lookup
("java:comp/env/tm/default");
// Execute timer every 10 seconds starting immediately
tm.schedule (new MyTimerListener(), 0, 10*1000);
out.println("<h4>Timer scheduled!</h4>");
} catch (NamingException ne) {
ne.printStackTrace();
out.println("<h4>Timer schedule failed!</h4>");
}
}

private static class MyTimerListener implements TimerListener {
public void timerExpired(Timer timer) {
System.out.println("timer expired called on " + timer);
// some useful work here ...
// let's just cancel the timer
System.out.println("cancelling timer ...");
timer.cancel();
}
}
}

ジョブ・スケジューラの使用

この節では、ジョブ・スケジューラ機能の使用方法について説明します。ジョブ・スケジューラを使用すると、クラスタリング環境内にcommonj.timer APIを実装できます。

ジョブ・スケジューラは、基本的にはcommonj.timer APIパッケージの実装であり、クラスタ内で使用できます。ここではジョブはcommonj.timers.TimerListenerインスタンスとして定義され、ジョブ・スケジューラに送信されて実行されます。

この節では、以下のトピックを取り上げます。

- タイマーのライフ・サイクル

- ジョブ・スケジューラの実装と構成

- サポートされていないメソッドおよびインタフェース

タイマーのライフ・サイクル

アプリケーション内にcommonj.timer APIを実装する場合、タイマーに構成できるライフ・サイクルには2種類あります。

- ローカル・タイマー
ローカル・タイマーは単一のサーバーJVM内でスケジューリングされ、ライフ・サイクル全体にわたってこのJVM内で処理されます。ローカル・タイマーはこのJVMが動作している限り動作し続け、JVMが終了すると失敗します。サーバー起動後のタイマーの再スケジューリングはアプリケーションが行います。

これはcommonj.timersの基本実装であり、これについては「Timer APIの概要」で説明しています。

- クラスタ全体タイマー
クラスタ全体タイマーはクラスタ内の各サーバーを含む他のJVMを認識し、そのため、ロード・バランシングとフェイルオーバーが可能です。クラスタ全体タイマーのライフ・サイクルは作成したサーバーにとらわれず、クラスタのライフ・サイクルにわたって機能し続けます。クラスタ・メンバーの少なくとも1つが有効である限り、このタイマーは機能を続けます。この機能はジョブ・スケジューラと呼ばれます。

ジョブ・スケジューラのTimer APIの実装では、「Timer APIの実装」にリストされている要件の他に、以下の要件が追加されます。

- タイマー・リスナー・クラスはシリアライズ可能でなければなりません。

- タイマー・リスナー・クラスはサーバー・システム・クラスパスに指定されていなければなりません。

- タイマーの再試行の最小時間は30秒。これは、ジョブ・スケジューラが30秒ごとに実行するタイマーを取得するためです。「ジョブ・スケジューラの使用」を参照してください。

各タイマーにはそれぞれメリットとデメリットがあります。ローカル・タイマーでは、複数のジョブをより短い時間間隔で処理できます。ジョブ・スケジューラでは、クラスタ内の永続性要件のために同様の精度ではジョブを処理できません。一方で、初めにタスクを作成したサーバーが失敗した場合にもそのタスクを実行する必要がある場合には、ジョブ・スケジューラの方が適しています。

ジョブ・スケジューラの実装と構成

この節では、アプリケーション内にジョブ・スケジューラを実装し、それを利用するようにWebLogic Server環境を構成するための基本的な手順を簡単に示します。

データベースの構成

永続性を保持し、タイマーがクラスタを認識できるようにするため、ジョブ・スケジューラにはデータベース接続が必要です。ジョブ・スケジューラ機能では、サーバーの移行でサポートされるのと同じデータベース・ベンダーおよびバージョンがサポートされます。

便宜上、セッション永続性、サーバーの移行などに使用されているのと同じデータベースを使用できます。たとえば、サーバーの移行におけるソース・データの選択および作成の手順については、Oracle WebLogic Server管理コンソール・ヘルプのクラスタ内のサーバーの移行の構成に関する項を参照してください。

データベースには、WEBLOGIC_TIMERSという表を作成する必要があります。サポートされるデータベースにこの表を作成するためのスキーマは、以下にあります。

WL_HOME/server/db/dbname/scheduler.ddl

where dbname is the name of the database vendor.

データ・ソースの構成

必要なスキーマで表を作成した後には、クラスタ構成内から参照されるデータ・ソースを定義する必要があります。ジョブ・スケジューラ機能は、ClusterMBeanのDataSourceForJobScheduler属性に有効なデータ・ソースが定義されている場合にのみ利用できます。これは、WebLogic Server管理コンソールで構成可能です。Oracle WebLogic Server管理コンソール・ヘルプのジョブ・スケジューラのデータ・ソースの構成に関する項を参照してください。

この定義の仕方について、以下のconfig.xmlからの抜粋に示します。

<domain>
...
<cluster>
<name>Cluster-0</name>
<multicast-address>239.192.0.0</multicast-address>
<multicast-port>7466</multicast-port>
<data-source-for-job-scheduler>JDBC Data     Source-0</data-source-for-job-scheduler>
</cluster>
...
<jdbc-system-resource>
<name>JDBC Data Source-0</name>
<target>myserver,server-0</target>
<descriptor-file-name>jdbc/JDBC_Data_Source-0-3407-jdbc.xml</descriptor-file-name>
</jdbc-system-resource>
</domain>

リース

ジョブ・スケジューラでは、リースが有効になっている必要があります。リースは、高可用性データベース・リースまたは非データベース・コンセンサス・リースのいずれかを使用できます。

リースの詳細は、『Oracle WebLogic Serverクラスタの使用』のリースに関する項を参照してください。

高可用性データベース・リースを使用する場合、データベースにリース表を作成する必要があります。サポートされるデータベースにこの表を作成するためのスキーマは、以下にあります。

WL_HOME/server/db/dbname/leasing.ddl

dbnameはデータベース・ベンダーの名前です。

ジョブ・スケジューラ内でJNDIアクセス

クラスタリングされたタイマー内でJNDIルックアップを実行する手順は、一般的なcommonj.timer APIにおける手順とは異なります。JNDIルックアップをTimerManagerにキャストする方法を以下の抜粋コードに示します。

InitialContext ic = new InitialContext();
commonj.timers.TimerManager jobScheduler =(common.timers.TimerManager)ic.lookup
("weblogic.JobScheduler");
commonj.timers.TimerListener timerListener = new MySerializableTimerListener();
jobScheduler.schedule(timerListener, 0, 30*1000);
// execute this job every 30 seconds

ジョブの取消

ジョブは、プログラムまたは管理コンソールを使用して取り消すことができます。

プログラムを使用してジョブを取り消すには、そのジョブの対応するJobRuntimeMBeanのcancel()メソッドを呼び出します。JobRuntimeMBeansには、以下のいずれかの方法でアクセスできます。

- スケジュールされたジョブのIDを使用してJobSchedulerRuntimeMBean.getJob(id)を呼び出します。IDは、JobScheduler.schedule()メソッドを呼び出して取得したTimerオブジェクトのtoString()メソッドから取得します。

- JobSchedulerRuntimeMBean.getExecutedJobs()を呼び出して、少なくとも1回は実行したすべてのジョブのJobRunTimesの配列を取得します。

cancel()メソッドを使用して、1回も実行していないスケジュールされたジョブを取り消すことはできません。

管理コンソールを使用してジョブを取り消す方法については、管理コンソール・オンライン・ヘルプの「ジョブの取消し」を参照してください。

デバッグ

以下のデバッグ・フラグを使用すると、より冗長な出力が可能になります。

-Dweblogic.debug.DebugSingletonServices=true -Dweblogic.JobScheduler=true

サポートされていないメソッドおよびインタフェース

commonj.timer APIのメソッドおよびインタフェースの中には、ジョブ・スケジューラ環境でサポートされていないものもあります。以下のメソッドおよびインタフェースはサポートの対象外です。

- CancelTimerListenerインタフェース

- StopTimerListenerインタフェース

- TimerManagerインタフェースの以下のメソッド

- suspend()

- resume()

- scheduleAtFixedRate()

- stop()

- waitForStop()

- waitForSuspend()

Work Manager APIとは

Work Manager (commonj.work) APIは、アプリケーションがコンテナ内で複数の作業項目を同時に実行できるようにするインタフェースを提供します。

基本的に、このAPIはjava.lang.Thread APIのコンテナ管理の代替機能を提供します。後者は、管理対象のJava EE環境でホストされるアプリケーション内では使用しないようにする必要があります。Work Manager APIを使用するとコンテナが実行中のすべてのスレッドを可視性および制御できるので、そうした環境ではかわりにWork Manager APIを使用するようお薦めします。

注意:
Work Manager APIでは、フェイルオーバーや永続性メカニズムは提供されません。管理対象サーバー環境が失敗または停止した場合、現在の作業はすべて失われます。

ワーク・マネージャのインタフェース

この節では、Work Manager APIに定義されているインタフェースの全般的な概要を説明します。これらのインタフェースの詳細な使用方法については、commonj.workパッケージのjavadocを参照してください。

Work Manager APIには以下のインタフェースがあります。

- WorkManager - このインタフェースは、実行する作業のスケジューリングに使用するスケジューリング・メソッド群を提供します。
WorkManagerはサーバー・レベルでシステム管理者が定義します。WorkManagerインスタンスはJNDIルックアップを実行して取得します。管理対象の環境では、複数のWorkManagerインスタンスをサポートできます。『Oracle WebLogic Server JNDIのプログラミング』を参照してください。WorkManagerはデプロイメント中にresource-refとして構成します。「ワーク・マネージャのデプロイメント」を参照してください。

アプリケーション・レベルでは、WorkManagerの各インスタンスがWorkItemを返します。アプリケーション内にWorkManagerを実装する方法の詳細は、WorkManagerのjavadocを参照してください。

- Work - このインタフェースを使用すると、アプリケーション・コードを非同期的に実行できます。このインタフェースを実装するクラスを作成することで、コード・ブロックを作成して特定の時刻または定義した間隔で実行するようにスケジューリングできます。これがすなわち、Work Manager API内で処理される「作業」です。

- WorkItem - WorkインスタンスがWorkManagerに送信された後で、WorkManagerはWorkItemを返します。WorkItemは完了したWorkインスタンスのステータスの判断に使用されます。

- WorkListener - WorkListenerインタフェースは、Workインスタンス内に定義されたスケジューリング済み作業とWorkManagerとの通信機能を提供するコールバック・インタフェースです。
WorkListenerを使用するとWork項目の現在のステータスを判断できます。詳細については、WorkListenerのjavadocを参照してください。

注意:
WorkListenerインスタンスは、WorkManager経由でWorkをスケジューリングするのに使用した元のスレッドと常に同じJVMで実行されます。

- WorkEvent - WorkEventは、WorkManagerによってWorkが処理されたときにWorkListenerに送信されます。

- RemoteWorkItem - RemoteWorkItemインタフェースはWorkItemインタフェースの拡張で、作業をリモートに実行できるようにします。このインタフェースを使用すると、クラスタの任意のメンバーで実行される作業をシリアライズできます。

ワーク・マネージャのデプロイメント

ワーク・マネージャは、サーバー・レベルで、適切なデプロイメント記述子のresource-refを使用して定義します。様々な記述子がありますが、特にweb.xmlまたはejb-jar.xmlが定義場所になります。

以下のデプロイメント記述子からの抜粋に、WorkManagerの構成方法を示します。

...
<resource-ref>
<res-ref-name>wm/MyWorkManager</res-ref-name>
<res-type>commonj.work.WorkManager</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
...

注意:
WorkManagerオブジェクトのJNDIネームスペースに推奨される接頭辞はjava:comp/env/wmです。

ワーク・マネージャのサンプル

この節には、HTTPサーブレット内でCommonJワーク・マネージャを使用する作業コードのサンプルを示します。

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import weblogic.work.ExecuteThread;
import commonj.work.WorkManager;
import commonj.work.Work;
import commonj.work.WorkException;

public class HelloWorldServlet extends HttpServlet {

public void service(HttpServletRequest req, HttpServletResponse res)
throws IOException
{
res.setContentType("text/html");
PrintWriter out = res.getWriter();

try {
InitialContext ic = new InitialContext();
System.out.println("## [servlet] executing in: " +
((ExecuteThread)Thread.currentThread()).getWorkManager()
.getName());
WorkManager wm = (WorkManager)ic.lookup
("java:comp/env/foo-servlet");
System.out.println("## got Java EE work manager !!!!");
wm.schedule(new Work(){
public void run() {
ExecuteThread th = (ExecuteThread) Thread.currentThread();
System.out.println("## [servlet] self-tuning workmanager: " +
th.getWorkManager().getName());
}
public void release() {}

public boolean isDaemon() {return false;}
});
}
catch (NamingException ne) {
ne.printStackTrace();}

catch (WorkException e) {
e.printStackTrace();
}

out.println("<h4>Hello World!</h4>");
// Do not close the output stream - allow the servlet engine to close it
// to enable better performance.
System.out.println("finished execution");}

}

ドキュメントのアクセシビリティについて

Oracleのアクセシビリティについての詳細情報は、Oracle Accessibility ProgramのWebサイトhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=docaccを参照してください。

Oracleサポートへのアクセス

Oracleのお客様は、My Oracle Supportにアクセスして電子サポートを受けることができます。詳細情報はhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=infoか、聴覚に障害があるお客様はhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=trsを参照してください。

Oracle Fusion Middleware Oracle WebLogic Server Timer and Work Manager API(CommonJ)プログラマーズ・ガイド, 11g リリース1 (10.3.6)

B61632-04

Copyright © 2007, 2011, Oracle and/or its affiliates.All rights reserved.

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクル社までご連絡ください。

このソフトウェアまたは関連ドキュメントを、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供する場合は、次の通知が適用されます。

U.S. GOVERNMENT RIGHTS Programs, software, databases, and related documentation and technical data delivered to U.S. Government customers are "commercial computer software" or "commercial technical data" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations.As such, the use, duplication, disclosure, modification, and adaptation shall be subject to the restrictions and license terms set forth in the applicable Government contract, and, to the extent applicable by the terms of the Government contract, the additional rights set forth in FAR 52.227-19, Commercial Computer Software License (December 2007).Oracle America, Inc., 500 Oracle Parkway, Redwood City, CA 94065.

このソフトウェアもしくはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアもしくはハードウェアは、危険が伴うアプリケーション(人的傷害を発生させる可能性があるアプリケーションを含む)への用途を目的として開発されていません。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用する際、安全に使用するために、適切な安全装置、バックアップ、冗長性(redundancy)、その他の対策を講じることは使用者の責任となります。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、オラクル社およびその関連会社は一切の責任を負いかねます。

OracleおよびJavaはOracle Corporationおよびその関連企業の登録商標です。その他の名称は、それぞれの所有者の商標または登録商標です。

Intel、Intel Xeonは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Opteron、AMDロゴ、AMD Opteronロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXは、The Open Groupの登録商標です。

このソフトウェアまたはハードウェア、そしてドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても、一切の責任を負いかねます。

Copyright © 2007, 2011, Oracle and/or its affiliates. All rights reserved.