この章では、Oracle Application Server Containers for J2EEで使用するジョブの追加および削除方法について説明します。次のトピックについて説明します。
ジョブを実行する前に、ジョブ・スケジューラにそのジョブを発行する必要があります。
ジョブを追加するには、oracle.ias.scheduler.Executableインタフェースを実装し、oracle.ias.scheduler.Scheduler.add() APIメソッドを使用してジョブをジョブ・スケジューラに発行する必要があります。
add()の詳細は『Oracle Containers for J2EE Job Scheduler API Reference』を参照してください。
oracle.ias.scheduler.Executableインタフェースは、次のように定義されています。
public interface Executable {
public void execute (JobContext context) throws JobExecutionException, JobCancellationException;
}
このインタフェースでは、ジョブ・スケジューラによってJavaクラスが呼び出される条件を指定します。ジョブ・スケジューラに発行されるすべてのJavaクラスがこのインタフェースを実装する必要があります。
|
注意: このインタフェースを実装するクラスは空のコンストラクタを提供する必要があります。発行されたジョブを実行するたびに、このコンストラクタを使用してオブジェクトの新規インスタンスが作成されます。このため、インスタンスや状態を維持する静的メンバー変数に依存してジョブを実装することはできません。 |
execute()メソッドは、関連付けられたジョブのトリガーが起動すると、ジョブ・スケジューラによって呼び出されます。入力変数としてoracle.ias.scheduler.JobContextオブジェクトを使用して、ジョブ定義に関連するすべての関連メタデータを調べて評価し、ロギング・サブシステムにアクセスするジョブを有効にします。
oracle.ias.scheduler.JobContextオブジェクトは、次のメソッドを提供します。
getLogger()
このメソッドは、アプリケーションのログを参照する、JDK 1.4準拠のログ出力オブジェクトjava.util.logging.Loggerを返します。
getJob()
このメソッドは、ジョブの構成情報へのアクセスに使用するoracle.ias.scheduler.Jobオブジェクトを返します。
oracle.ias.scheduler.JobContextオブジェクトにより、ジョブのデータおよび関連付けられたサブシステムにアクセスできます。詳細は、『Oracle Containers for J2EE Job Scheduler API Reference』を参照してください。
ジョブを実行するには、その前にジョブ・スケジューラに発行する必要があります。この処理には、oracle.ias.scheduler.Scheduler.add()メソッドを使用します。発行時に、java.util.Propertiesオブジェクトを使用して、入力パラメータを名前と値のペアで指定できます。メンテナンスと再使用のために、できるかぎりジョブ・パラメータを使用してください(例2-1を参照)。
oracle.ias.scheduler.Scheduler.add()メソッドを使用すると、ジョブをスケジュールまたはトリガー、あるいはその両方とともに追加できます。
ジョブを発行すると、指定されたスケジュールまたはトリガーに従って、指定されたクラスがジョブ・スケジューラによって実行されます。スケジュールが繰り返されない場合、タイマーの有効期限切れ通知が関連付けられたトリガーに送信された後、ジョブは無効になります。
ジョブが正常に発行されると、oracle.ias.scheduler.JobHandleオブジェクトが返されます。このオブジェクトは、発行されたジョブへのハンドルとして機能します。このハンドルを使用して、ジョブで特定の管理タスクを実行できます(ジョブの一時停止など)。さらに、このオブジェクトを後で使用するために、アプリケーションにより格納しておくことも可能です。
add()メソッドは、トランザクション・サポートを提供します。なんらかの理由でトランザクションがロールバックされた場合、操作が取り消され、ジョブは作成されません。また、トランザクションがコミットされるまでジョブは実行されません。
ここでは、ジョブを実装してジョブ・スケジューラに発行する例を示します。
例2-1 バックアップを実行するジョブの実装
シナリオ: レガシー・アプリケーションをJ2EE環境に移行しました。その一部にはファイル・システムに格納されるデータが含まれています。J2EEアプリケーションの一部として、定期的にデータをバックアップするジョブが必要です。ジョブには2つの入力パラメータが必要です。
ソース・ディレクトリ: ファイルのコピー元のディレクトリ
宛先ディレクトリ: ファイルのコピー先のディレクトリ
ソース・ディレクトリと宛先ディレクトリは、ジョブ実装に含めることもできました。しかし、これらをジョブ・プロパティのパラメータとして指定すると、ジョブを変更することなく再使用できます。プロパティの指定方法の例については、例2-2を参照してください。
import java.io.File;
import java.io.IOException;
import oracle.ias.scheduler.Job;
import oracle.ias.scheduler.Executable;
import oracle.ias.scheduler.JobContext;
import oracle.ias.scheduler.JobExecutionException;
public class BackupJob implements Executable {
public void execute(JobContext context) throws JobExecutionException {
// retrieve the source/destination directories
Job job = context.getJob();
String source = job.getProperties().getProperty("SourceDirectory");
String destination = job.getProperties().getProperty("DestinationDirectory");
// get the list of files to copy
File directory = new File(source);
File[] files = directory.listFiles();
// copy the files
Runtime runtime = Runtime.getRuntime();
Process process;
for (int x = 0; x < files.length; x++) {
try {
process = runtime.exec("/bin/cp " + files[x].toString() +
" " + destination);
process.waitFor();
} catch(IOException e) {
throw new RuntimeException("copy failed: "+files[x],e);
} catch(InterruptedException e) {
throw new RuntimeException("copy failed: "+files[x],e);
}
}
}
}
ソース・ディレクトリと宛先ディレクトリの取得に、getProperty()オブジェクトが使用されています。これらのディレクトリをジョブ実装で直接指定するかわりに、ジョブをジョブ・スケジューラに発行する際に指定します(例2-2を参照)。
execute()メソッドを使用することで、oracle.ias.scheduler.Executableインタフェースの実装条件が整います。このメソッドは、ジョブを実行するたびに呼び出されます。
例2-2 ジョブ・プロパティの指定とジョブの発行
ジョブを作成したら、そのジョブをジョブ・スケジューラに発行する必要があります。ジョブは、ジョブ・スケジューラが提供するadd()メソッドを使用して発行されます。次のコード例は、ジョブをプロパティ(ここでは、ソース・ディレクトリと宛先ディレクトリ)とともに発行する方法を示しています。
// set up the properties
java.util.Properties properties = new Properties();
properties.put("SourceDirectory","/mnt/data");
properties.put("DestinationDirectory","/mnt/backup");
// submit the job
jobHandle = scheduler.add("file backup job, runs every week",
new BackupJob().getClass().getName(),
new Schedule(),
properties);
ジョブ・プロパティとスケジュールは、ジョブをジョブ・スケジューラに発行するときに指定されます。スケジュール・オプションの指定の詳細は、第3章を参照してください。
Java Naming and Directory Interface(JNDI)は、JavaベースのアプリケーションがJavaオブジェクトを格納および取得できるネイティブのJava APIです。Javaアプリケーションの命名サービスとディレクトリ・サービスを提供し、任意のタイプの指定Javaオブジェクトを格納および取得できるようにします。
次のコード例は、JNDIルックアップを実行してジョブ・スケジューラにアクセスする方法を示しています。
InitialContext ic = new InitialContext();
Object objRef = ic.lookup("java:comp/env/ejb/scheduler");
SchedulerHome home = (SchedulerHome)
PortableRemoteObject.narrow(objRef, SchedulerHome.class);
Scheduler scheduler = home.create();
JNDIの詳細は、次のサイトを参照してください。
http://java.sun.com/products/jndi/index.jsp
ジョブの発行後、oracle.ias.scheduler.Scheduler.remove()メソッドを使用して、そのジョブを削除できます。このメソッドでは、実行中のジョブは削除されませんが、ジョブ定義は削除されるため、今後ジョブの実行は発生しません。
remove()メソッドの詳細は、『Oracle Containers for J2EE Job Scheduler API Reference』を参照してください。
次のコード例は、例2-1で実装し、例2-2で発行したBackupJobジョブを削除する方法を示しています。
現在実行中のジョブを停止するには、ジョブを取り消す必要があります。ジョブの取消しの詳細は、第6章を参照してください。
スケジュールされているジョブの実行を停止し、かつジョブを後で実行できるようにジョブ定義をシステムから削除しないようにするには、ジョブを一時停止する必要があります。ジョブの一時停止の詳細は、第5章を参照してください。
すべてのジョブのメタデータは実行時に使用可能になります。oracle.ias.scheduler.JobContextオブジェクトを使用してアクセスします。
入力パラメータを使用すると、ジョブの再使用が容易になります。実装中に、入力パラメータを指定し、必要に応じてプロパティを使用します。
取消しが必要なジョブには、oracle.ias.scheduler.Cancellableインタフェースを使用します。このインタフェースを使用せずにジョブを取り消そうとすると、例外が発生します。
execute()メソッドを実装した場合、最終的に制御をコール元に戻す必要があります。条件が満たされるまでに長時間(1分以上など)を要するアプリケーション条件を基に、ジョブの完了を制御しないでください。かわりにトリガーを使用して、アプリケーションの条件が満たされたときにジョブを実行するようにしてください。こうすることで、アプリケーションが必要とする処理リソースを最小限に抑えることができます。
ジョブの状態は、アクティブ、一時停止、完了の3つのうちのいずれかです。
アクティブな状態のジョブは、通知を受け取り、トリガー式を評価できます。アクティブ状態でトリガーがtrueと評価された場合、ジョブが実行され、トリガーはfalseにリセットされます。
一時停止状態のジョブは、通知を受け取り、トリガー式を評価できます。しかし、一時停止状態でトリガーがtrueと評価されても、トリガーはfalseにリセットされず、ジョブの実行は抑止されます。
完了状態(スケジュールベースのジョブに有効な状態)の場合、ジョブのスケジュールが完了し、新しいジョブをスケジュールできなくなります。ジョブがスケジュールベースではない場合、完了状態になることはありません。スケジュールベースのジョブの詳細は、第3章を参照してください。
ジョブを削除すると、(実行に失敗したジョブの)未処理の再試行および(一時停止されたジョブの)再実行も削除されますか。
はい。ジョブを削除すると、ジョブの実行は発生しません。