Oracle WebLogic Server CommonJアプリケーションの開発
12c (12.1.2)
E48044-01(原本部品番号:E28130-01)
2013年6月
この節では、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は次の3つのインタフェースで構成されています。
TimerManager
TimerListener
タイマー
TimerManager
インタフェースは、管理対象の環境においてタイマーを作成および使用するためのフレームワークを提供します。TimerListener
は、タイマー通知を受信します。TimerManager.schedule
メソッドを使用して、TimerListener
を特定の時刻または間隔において実行するようにスケジューリングします。
タイマーの実装方法の詳細は、「Timer APIの使用」を参照してください。
TimerManager
インタフェースは、アプリケーション内の全般的なスケジューリング・フレームワークを提供します。管理対象の環境では、複数のTimerManager
インスタンスをサポートできます。1つのアプリケーション内に複数のTimerManager
インスタンスを設定できます。
TimerManager
は、デプロイ中にデプロイメント記述子で構成されます。TimerManager
の定義には、実装固有の付加的な構成情報が含まれることもあります。
TimerManager
をデプロイメント記述子で定義したら、そのインスタンスには、ローカルJava環境でJNDI参照を使用してアクセスできます。TimerManager
でJNDI lookup()
を呼び出すたびに、TimerManager
の新しい論理インスタンスが返されます。
TimerManager
インタフェースはスレッドセーフです。
JNDIの使用の詳細は、『Oracle WebLogic Server JNDIアプリケーションの開発』を参照してください。
TimerManager
は、suspend
メソッドおよびresume
メソッドを使用して中断および再開できます。TimerManager
を中断すると、未処理のタイマーはすべてTimerManager
が再開されるまで保留されます。
この項では、アプリケーション内のTimer APIの使用に必要な手順を説明します。
アプリケーションをデプロイする前に、タイマー・マネージャへのリソース参照を含むデプロイメント記述子が作成済であることを確認してください。
これによって、JNDIを使用してTimerManager
をアクセスできるようになります。JNDIルックアップの詳細は、Oracle WebLogic Server JNDIアプリケーションの開発を参照してください。
Timer APIを実装するには、次の手順を実行します。
commonj.timers.*
パッケージをインポートします。
InitialContext
を作成します。これによりTimerManager
がJNDIでルックアップ可能になります。たとえば:
InitialContext inctxt = new InitialContext();
JNDIルックアップの詳細は、Oracle WebLogic Server JNDIアプリケーションの開発を参照してください。
TimerManager
のJNDIルックアップに基づいて新しいTimerManager
を作成します。たとえば:
TimerManager mgr = (TimerManager)ctx.lookup('java:comp/env/timer/MyTimer');
この文ではJNDIルックアップの結果がTimerManager
にキャストされています。
タイマー通知を受信するためにTimerListener
を実装します。たとえば:
TimerListener listener = new StockQuoteTimerListener('abc', 'example');
TimerManager.schedule
メソッドを呼び出します。たとえば:
mgr.schedule(listener, 0, 1000*60)
schedule
メソッドはTimer
オブジェクトを返します。
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
パッケージの基本実装です。
クラスタ全体タイマー
クラスタ全体タイマーはクラスタ内の各サーバーを含む他のJVMを認識し、そのため、ロード・バランシングとフェイルオーバーが可能です。クラスタ全体タイマーのライフ・サイクルは作成したサーバーにとらわれず、クラスタのライフ・サイクルにわたって機能し続けます。クラスタ・メンバーの少なくとも1つが有効であるかぎり、このタイマーは機能を続けます。この機能はジョブ・スケジューラと呼ばれます。
ジョブ・スケジューラのTimer APIの実装では、「Timer APIの実装」にリストされている要件の他に、次の要件が追加されます。
タイマー・リスナー・クラスはシリアライズ可能である必要があります。
タイマー・リスナー・クラスはサーバー・システム・クラスパスに指定されていなければなりません。
タイマーの再試行の最小時間は30秒。これは、ジョブ・スケジューラが30秒ごとに実行するタイマーを取得するためです。
各タイマーにはそれぞれメリットとデメリットがあります。ローカル・タイマーでは、複数のジョブをより短い時間間隔で処理できます。ジョブ・スケジューラでは、クラスタ内の永続性要件のために同様の精度ではジョブを処理できません。一方で、初めにタスクを作成したサーバーが失敗した場合にもそのタスクを実行する必要がある場合には、ジョブ・スケジューラの方が適しています。
この項では、アプリケーション内にジョブ・スケジューラを実装し、それを利用するようにWebLogic Server環境を構成するための基本的な手順を簡単に示します。以下の内容について説明します。
永続性を保持し、タイマーがクラスタを認識できるようにするため、ジョブ・スケジューラにはデータベース接続が必要です。ジョブ・スケジューラ機能では、サーバーの移行でサポートされるのと同じデータベースがサポートされます。
便宜上、セッションの持続やサーバー移行などに使用されるものと同一のデータベースを使用できます。たとえば、サーバーの移行におけるデータ・ソースを選択および作成する方法は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのクラスタ内のサーバーの移行の構成に関する項を参照してください。
データベースで、WEBLOGIC_TIMERS
という表を作成する必要があります。この表を作成するためのスキーマは、次の場所にあります。
WL_HOME/server/db/dbname/scheduler.ddl
前述のパスで、dbname
はデータベース名を示します。
必要なスキーマで表を作成した後には、クラスタ構成内から参照されるデータ・ソースを定義する必要があります。ジョブ・スケジューラ機能は、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>
ジョブ・スケジューラでは、リースが有効になっている必要があります。リースは、高可用性データベース・リースまたは非データベース・コンセンサス・リースのいずれかを使用できます。高可用性データベース・リースを使用する場合、データベースにリース表を作成する必要があります。
この表を作成するためのスキーマは、次の場所にあります。
WL_HOME/server/db/dbname/leasing.ddl
前述のパスで、dbname
はデータベース名を示します。
詳細は、Oracle WebLogic Serverクラスタの管理のリースに関する項を参照してください。
クラスタリングされたタイマー内で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
ジョブは、プログラムまたはWebLogic Server管理コンソールを使用して取り消すことができます。
プログラムを使用してジョブを取り消すには、そのジョブの対応するJobRuntimeMBeanのcancel
メソッドを呼び出します。JobRuntimeMBeanには、次のいずれかの方法でアクセスできます。
スケジュールされたジョブのIDを使用してJobSchedulerRuntimeMBean.getJob(id)
を呼び出します。IDは、JobScheduler.schedule
メソッドを呼び出して取得したTimerオブジェクトのtoString
メソッドから取得します。
JobSchedulerRuntimeMBean.getExecutedJobs()
を呼び出して、少なくとも1回は実行したすべてのジョブのJobRunTimes
の配列を取得します。
cancel
メソッドを呼び出して、1回も実行していないスケジュールされたジョブを取り消すことはできません。
WebLogic Server管理コンソールを使用してジョブを取り消す方法の詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのジョブの取消しに関する項を参照してください。
以下のデバッグ・フラグを使用すると、より冗長な出力が可能になります。
-Dweblogic.debug.DebugSingletonServices=true -Dweblogic.JobScheduler=true
commonj.timer
パッケージの次のメソッドおよびインタフェースは、ジョブ・スケジューラ環境でサポートされていません:
CancelTimerListener
インタフェース
StopTimerListener
インタフェース
TimerManager
インタフェースの以下のメソッド
suspend
resume
scheduleAtFixedRate
stop
waitForStop
waitForSuspend
Work Manager API (commonj.work
)は、アプリケーションがコンテナ内で複数の作業項目を同時に実行できるようにするインタフェースのセットを提供します。
基本的に、このAPIはjava.lang.Thread
APIのコンテナ管理の代替機能を提供します。後者は、管理対象のJava EE環境でホストされるアプリケーション内では使用しないようにする必要があります。Work Manager APIを使用するとコンテナが実行中のすべてのスレッドを可視性および制御できるので、そうした環境ではかわりにWork Manager APIを使用するようお薦めします。
注意: Work Manager APIでは、フェイルオーバーや永続性メカニズムは提供されません。管理対象サーバー環境が失敗または停止した場合、現在の作業はすべて失われます。 |
この項では、Work Manager APIのインタフェースの概要を説明します。これらのインタフェースの使用の詳細は、Oracle WebLogic Server Java APIリファレンスのcommonj.work
に関する項を参照してください。
Work Manager APIには以下のインタフェースがあります。
WorkManager - 実行する作業のスケジューリングに使用するスケジューリング・メソッドのセットを提供します。
WorkManagerはサーバー・レベルでシステム管理者が定義します。WorkManager
インスタンスはJNDIルックアップを実行して取得します。管理対象の環境では、複数のWorkManager
インスタンスをサポートできます。WorkManagerはデプロイメント中にresource-refs
として構成します。「ワーク・マネージャのデプロイメント」を参照してください。
アプリケーション・レベルでは、WorkManager
の各インスタンスがWorkItem
を返します。アプリケーション内にWorkManager
を実装する方法の詳細は、Oracle WebLogic Server Java APIリファレンスのWorkManager
に関する項を参照してください。
JNDIの詳細は、Oracle WebLogic Server JNDIアプリケーションの開発を参照してください。
Work - アプリケーション・コードを非同期的に実行できます。このインタフェースを実装するクラスを作成することで、コード・ブロックを作成して特定の時刻または定義した間隔で実行するようにスケジューリングできます。これがすなわち、Work Manager API内で処理される「作業」です。
WorkItem - 完了したWork
インスタンスのステータスを判断します。WorkItem
は、Work
インスタンスがWorkManager
に送信された後、WorkManager
によって返されます。
詳細は、Oracle WebLogic Server Java APIリファレンスのWork
に関する項を参照してください。
WorkListener - Work
インスタンス内に定義されたスケジューリング済作業とWorkManager
との通信を提供します。WorkListener
は、コールバック・インタフェースです。
WorkListener
を使用するとWork
項目の現在のステータスを判断できます。詳細は、Oracle WebLogic Server Java APIリファレンスのWorkListener
に関する項を参照してください。
注意:
|
WorkEvent - WorkEvent
は、WorkManager
によってWork
が処理されたときにWorkListener
に送信されます。
詳細は、Oracle WebLogic Server Java APIリファレンスのWorkEvent
に関する項を参照してください。
RemoteWorkItem - RemoteWorkItem
インタフェースはWorkItem
インタフェースの拡張で、作業をリモートに実行できるようにします。このインタフェースを使用すると、クラスタの任意のメンバーで実行される作業をシリアライズできます。
詳細は、Oracle WebLogic Server Java APIリファレンスのRemoteWorkItem
に関する項を参照してください。
ワーク・マネージャは、サーバー・レベルで、適切なデプロイメント記述子の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> ...
注意:
|
次の例は、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 CommonJアプリケーションの開発, 12c (12.1.2)
E48044-01
Copyright © 2007, 2013, Oracle and/or its affiliates.All rights reserved.
このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。
ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクル社までご連絡ください。
このソフトウェアまたは関連ドキュメントを、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供する場合は、次の通知が適用されます。
U.S. GOVERNMENT END USERS: Oracle programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, delivered to U.S. Government end users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations.As such, use, duplication, disclosure, modification, and adaptation of the programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, shall be subject to license terms and license restrictions applicable to the programs.No other rights are granted to the U.S. Government.
このソフトウェアもしくはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアもしくはハードウェアは、危険が伴うアプリケーション(人的傷害を発生させる可能性があるアプリケーションを含む)への用途を目的として開発されていません。このソフトウェアまたはハードウェアを危険が伴うアプリケーションで使用する際、このソフトウェアまたはハードウェアを安全に使用するために、適切な安全装置、バックアップ、冗長性、その他の対策を講じることは使用者の責任となります。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、オラクル社およびその関連会社は一切の責任を負いかねます。
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の登録商標です。
このソフトウェアまたはハードウェア、そしてドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても、一切の責任を負いかねます。