JBPM リファレンスガイド
JBoss Enterprise SOA Platform 5
JBoss 開発者向け
5.3.1 エディッション
概要
このガイドでは、JBoss Enterprise SOA Platform で JBPM と JPDL を使用する方法を説明します。
第1章 はじめに リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
この ガイド は、開発者および管理者向けに書かれています。企業環境で jBPM と JPDL を使用する方法を学ぶ際にお読みください。本書は、ソフトウェアの使用方法を説明するだけでなく、その仕組みについても非常に詳細に説明しています。
注記
この ガイド には、多くの用語が含まれています。主な用語の定義は、「 役に立つ定義 」 を参照してください。
JBoss Business Process Manager (jBPM) は、プロセス言語の柔軟で拡張可能な基盤です。jBPM Process Definition Language (JPDL) は、このフレームワークの上に構築された プロセス言語 の 1 つです。これは、ユーザーがビジネスプロセスをグラフィカルに表現できるように設計された直感的な言語です。この表現は、タスク、待機状態 (非同期通信の場合)、タイマー、および自動化された アクション を表すことによって行われます。これらの操作をまとめてバインドするために、言語には強力で拡張可能な 制御フローメカニズムが あります。
JPDL には依存関係がほとんどないため、Java ライブラリーと同じくらい簡単にインストールできます。これを行うには、JPDL を クラスター化された J2EE アプリケーションサーバー にデプロイします。これは、極端なスループットが重要な要件である環境で特に役立ちます。
注記
JPDL は、任意のデータベースで使用できるように設定できます。また、任意のアプリケーションサーバーにデプロイすることもできます。
1.1. 概要 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
このセクションでは、jBPM の動作方法の概要を説明します。
中核となるワークフローおよびビジネスプロセス管理機能は、シンプルな Java ライブラリーとしてパッケージ化されています。このライブラリーには、JPDL データベースプロセスを管理および実行するサービスが含まれています。
図1.1 jPDL コンポーネントの概要
1.2. jPDL スイート リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
このスイートには、すべての jBPM コンポーネントと次のサブディレクトリーが含まれています。
- config
- database
- deploy
- designer
- examples
- lib
- src
JBoss Application Server は、次のコンポーネントで構成されています。
- jBPM Web コンソール
- これは Web アーカイブとしてパッケージ化されています。プロセス参加者 と jBPM 管理者の両方がこのコンソールを使用できます。
- jBPM テーブル
- これらは、デフォルトの Hypersonic データベースに含まれています。(このデータベースには、すでにプロセスが含まれています。)
- サンプルプロセス
- 1 つのサンプルプロセスが、すでに jBPM データベースにデプロイされています。
- アイデンティティーコンポーネント
- アイデンティティーコンポーネントライブラリーは、コンソール Web アプリケーション の一部です。データベース内にある
JBPM_ID_接頭辞を持つテーブルを所有しています。
1.3. jPDL グラフィカルプロセスデザイナー リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
jPDL には、グラフィカルプロセスデザイナー も含まれています。これは、ビジネスプロセスの設計に使用します。(これは Eclipse プラグインであり、JBoss Developer Studio 製品に含まれています。)
ビジネスプロセスのモデリングから実際の実装へのスムーズな移行を容易にし、ビジネスアナリストと技術開発者の両方に役立ちます。
1.4. jBPM コンソール Web アプリケーション リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
コンソール Web アプリケーション には、3 つの目的があります。1 つ目は、中心的なユーザーインターフェイスとしての機能です。ここでは、プロセスの実行によって生成されたランタイムタスクを操作できます。2 つ目は、ランタイムインスタンスを検査および操作できる管理コンソールおよびモニタリングコンソールとしての機能です。このソフトウェアの 3 つ目の機能は、ビジネスアクティビティーモニターとしての機能です。この機能は、プロセスの実行に関する統計を表示します。この情報を使用すれば、ボトルネックを発見して排除できるため、これはパフォーマンスの最適化を求めるマネージャーに役立ちます。
1.5. jBPM コアライブラリー リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
Business Process Manager には 2 つのコアコンポーネントがあります。これらは、プロセス定義を管理する "プレーン Java" (J2SE) ライブラリーと、プロセスインスタンスを実行するランタイム環境です。
jBPM 自体は Java ライブラリーです。したがって、Web アプリケーションや Swing アプリケーション、
Enterprise Java Bean、Web サービスなど、あらゆる Java 環境で使用できます。
jBPM ライブラリーを ステートレスセッション
Enterprise Java Bean としてパッケージ化して公開することもできます。クラスターデプロイメントを作成する必要がある場合、または非常に高いスループットを実現するためにスケーラビリティーを提供する必要がある場合は、これを行ってください。(ステートレスセッション Enterprise Java Bean は J2EE 1.3 仕様に準拠しているため、任意のアプリケーションサーバーにデプロイできます。)
jbpm-jpdl.jar ファイルの一部は、Hibernate や Dom4J などのサードパーティーライブラリーに依存していることに注意してください。
Hibernate は jBPM に 永続性 機能を提供します。また、従来の O/R マッピング を提供することとは別に、Hibernate は競合するデータベースで使用される構造化照会言語の方言間の違いを解決します。この機能により、jBPM は高い移植性を確保しています。
Business Process Manager のアプリケーションプログラミングインターフェイスは、Web アプリケーション、Enterprise Java Bean、Web サービスコンポーネント、メッセージ駆動型 Bean など、プロジェクト内の任意のカスタム Java コードからアクセスできます。
1.6. アイデンティティーコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
jBPM は、ユーザーデータ (およびその他の組織データ) を含む会社のディレクトリーと統合できます。(組織情報コンポーネントが利用できないプロジェクトの場合は、アイデンティティーコンポーネント を使用します。このコンポーネントには、従来のサーブレット、Enterprise Java Bean、およびポートレットで使用されるモデルよりも "豊富" なモデルがあります。)
注記
このトピックの詳細は、「 アイデンティティーコンポーネント 」 を参照してください。
1.7. jBPM ジョブエグゼキューター リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
JBoss jBPM ジョブエグゼキューター は、標準の Java 環境でジョブをモニタリングおよび実行する目的で設計されたコンポーネントです。ジョブ は、タイマーと非同期メッセージに使用されます。(エンタープライズ環境では、Java Message Service と Enterprise Java Bean
TimerService をこの目的に使用する場合があります。ジョブエグゼキューターは "標準" の環境で使用するのが最適です。)
Job Executor コンポーネントは、コア
jbpm-jpdl ライブラリーにパッケージ化されています。次の 2 つのシナリオのいずれかでのみデプロイできます。
JbpmThreadsServletがジョブエグゼキューターを起動するように設定されている場合。- 別個の Java 仮想マシンを起動し、その中からジョブエグゼキュータースレッドを実行できるようにした場合。
1.8. まとめ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
この章では、jBPM とその構成コンポーネントの概要を説明しました。
第2章 チュートリアル リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
次のチュートリアルでは、JPDL で基本的な プロセス構造 を使用する方法を説明します。このチュートリアルでは、アプリケーションプログラミングインターフェイスを介してランタイム実行を管理する方法も示します。
このチュートリアルの例は、
src/java.examples サブディレクトリーにある JBPM ダウンロードパッケージにあります。
注記
この時点でプロジェクトを作成することを推奨します。そうすることで、各例を自由に試したり、バリエーションを作成したりできます。
まず、JBPM をダウンロードしてインストールします。
jBPM には、例に示されている XML を作成するためのグラフィカルデザイナーツールが含まれています。グラフィカルデザイナーのダウンロード手順は、「ダウンロード可能なリソースの概要」セクションを参照してください。このチュートリアルを完了するためにグラフィカルデザイナーツールは必要ありません。
2.1. "Hello World" の例 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プロセス定義 は、ノードと遷移で構成される 有向グラフ です。
Hello World プロセス定義には、以下のノードが 3 つあります。(デザイナーツールl を使用せずにこの単純なプロセスを調べて、その仕組みを学習することをお勧めします。) 次の図は、Hello World プロセスをグラフィカルに表現したものです。
図2.1 Hello World プロセスの図
2.2. データベースの例 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
jBPM の基本的な機能の 1 つに、データベースプロセスが
待機状態 の間、データベースプロセスの実行を永続化する機能があります。次の例は、この機能を示しており、jBPM データベースにプロセスインスタンスを保存しています。
これは、ユーザーコードのさまざまな部分に対して個別の
メソッド を作成することによって機能します。たとえば、Web アプリケーション内のユーザーコードの一部がプロセスを起動し、データベース内で実行を "永続化" します。その後、メッセージ駆動型 Bean がそのプロセスインスタンスをロードし、その実行を再開します。
ここでは、ユーザーコードのさまざまな部分に対して個別の
メソッド が作成されます。たとえば、Web アプリケーションのコードがプロセスを起動し、データベース内で実行を "永続化" します。その後、メッセージ駆動型 Bean プロセスインスタンスをロードし、その実行を再開します。
注記
jBPM の永続性に関する詳細は、4章 永続性 を参照してください。
2.3. コンテキストの例: プロセス変数 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プロセスが実行されている間、コンテキスト情報は プロセス変数 に保持されます。これらは、変数名を値にマップするという点で
java.util.Map クラスに似ており、後者は Java オブジェクトに相当します。(プロセス変数は、プロセスインスタンスの一部として "永続化" されます。)
注記
次の例を単純にするために、変数を操作するために必要なアプリケーションプログラミングインターフェイスのみを示します (永続性機能はありません)。
注記
変数の詳細は、7章 コンテキスト を参照してください。
2.4. タスク割り当ての例 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
次の例は、ユーザーにタスクを割り当てる方法を示しています。jBPM ワークフローエンジンと組織モデルが分離しているため、式言語が常に限定されており、アクターの計算には使用できません。代わりに、
AssignmentHandler の実装を指定し、それを使用してタスクのアクターの計算を含めます。
2.5. カスタムアクションの例 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
アクション は、カスタム Java コードを jBPM プロセスにバインドするためのメカニズムです。アクションは独自のノードに関連付けることができます (これらがプロセスのグラフィカル表現に関連している場合)。 または、アクションをイベントに "配置" することもできます (たとえば、遷移を取得するとき、またはノードに進入または退出するときなど)。 アクションがイベントに配置されている場合、アクションはグラフィカル表現の一部として扱われません (ただし、ランタイムプロセスの実行中にイベントが "発生" すると、アクションは引き続き実行されます)。
最初に、次の例で使用されているアクションハンドラー
MyActionHandler の実装をご覧ください。それ自体は特に驚くようなものではありません。ブール型変数 isExecuted を true に設定しているだけです。この変数は静的であるため、アクションハンドラー内から (およびアクション自体から) アクセスして、その値を確認することができます。
注記
"アクション" の詳細は、「アクション」 を参照してください。
重要
各テストの前に、静的フィールド
MyActionHandler.isExecuted をfalse に設定してください。
// Each test will start with setting the static isExecuted
// member of MyActionHandler to false.
public void setUp() {
MyActionHandler.isExecuted = false;
}
// Each test will start with setting the static isExecuted
// member of MyActionHandler to false.
public void setUp() {
MyActionHandler.isExecuted = false;
}
最初の例は、遷移に対するアクションを示しています。
次の例は、
enter-node イベントと leave-node イベントの両方に同じアクションが配置されていることを示しています。ノードには複数のイベントタイプがあることに注意してください。これは、イベントが 1 つしかない 遷移 とは対照的です。したがって、ノードにアクションを配置するときは、常にイベント要素に配置してください。
第3章 設定 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
この章では、例を通じて jBPM の設定方法を説明します。
Business Process Manager を設定する最も簡単な方法は、
jbpm.cfg.xml 設定ファイルをクラスパスのルートに配置することです。ファイルをリソースとして使用できない場合は、代わりにデフォルトの最小設定が使用されます。この最小設定は jBPM ライブラリー (org/jbpm/default.jbpm.cfg.xml) に含まれています。 jBPM 設定ファイルが提供されている場合、そこに含まれる値がデフォルト値として使用されます。したがって、デフォルトの設定ファイルの値とは異なる値を指定するだけで済みます。
jBPM 設定は、
org.jbpm.JbpmConfiguration と呼ばれる Java クラスによって表されます。これは、シングルトン インスタンスメソッド (JbpmConfiguration.getInstance()) を使用して取得します。
注記
別のソースから設定をロードするには、
JbpmConfiguration.parseXxxx メソッドを使用します。
static JbpmConfinguration jbpmConfiguration = JbpmConfinguration.parseResource("my.jbpm.cfg.xml");
static JbpmConfinguration jbpmConfiguration = JbpmConfinguration.parseResource("my.jbpm.cfg.xml");
JbpmConfiguration は "スレッドセーフ" であるため、静的メンバー に保持できます。
すべてのスレッドは、
JbpmContext オブジェクトの ファクトリー として JbpmConfiguration を使用できます。JbpmContext は通常、1 つのトランザクションを表します。これらは、次のような コンテキストブロック 内でサービスを利用できるようにします。
JbpmContext は、一連のサービスと構成設定の両方を Business Process Manager で使用できるようにします。サービスは、jbpm.cfg.xml ファイルの値によって設定されます。これらは、環境内で利用可能なあらゆるサービスを使用して、jBPM を任意の Java 環境で実行できるようにします。
JbpmContext のデフォルトの構成設定は次のとおりです。
上記のファイルには、次の 3 つの部分が含まれています。
JbpmContextを設定する一連の サービス実装。(可能な設定オプションは、特定のサービスの実装に関する章で詳しく説明されています。)- 設定リソースへの参照をリンクするすべてのマッピング。設定ファイルの 1 つをカスタマイズする場合は、これらのマッピングを更新します。これを行うには、必ず最初にデフォルトの設定ファイル (
jbpm-3.x.jar) をクラスパス上の別の場所にバックアップしてください。その後、jBPM が使用するカスタマイズされたバージョンを指すように、このファイルの参照を更新してください。 - jBPM で使用するためのさまざまな設定。(これらは、該当する特定のトピックに関する章で説明されています。)
デフォルト設定は、依存関係が最小限の単純な Web アプリケーション環境向けに最適化されています。永続性サービスは、他のすべてのサービスで使用される JDBC 接続を取得します。したがって、すべてのワークフロー操作は、JDBC 接続上の単一のトランザクションに配置されるため、一元化されます (トランザクションマネージャーは必要ありません)。
JbpmContext には、ほとんどの一般的なプロセス操作のための 便利なメソッド が含まれています。これらを次のコードサンプルに示します。
注記
save メソッドを明示的に呼び出す必要はありません。
XxxForUpdate メソッドは、ロードされたオブジェクトを "自動保存" に登録するように設計されているためです。
複数の
jbpm-context を指定することができます。これを行うには、それぞれに一意の name 属性を指定する必要があります。(JbpmConfiguration.createContext(String name); を使用して、名前付きコンテキストを取得します。)
service 要素は、独自の名前と、関連する サービスファクトリー を指定します。このサービスは、
JbpmContext.getServices().getService(String name) によって作成を要求された場合にのみ作成されます。
注記
ファクトリー は、属性ではなく 要素 として指定することもできます。これは、一部の設定情報をファクトリーオブジェクトに挿入するときに必要です。
オブジェクトの作成とワイヤリング、および XML の解析を担当するコンポーネントは、
オブジェクトファクトリー と呼ばれることに注意してください。
3.1. ファクトリーのカスタマイズ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
警告
ファクトリーをカスタマイズする際によく発生する間違いは、長い表記と短い表記を混在させることです。(短い表記の例は、デフォルトの設定ファイルで確認できます。)
Hibernate は、
StateObjectStateException 例外をログに記録し、スタックトレース を生成します。後者を削除するには、org.hibernate.event.def.AbstractFlushingEventListener を FATAL に設定します。(log4j を使用している場合、削除するには設定に log4j.logger.org.hibernate.event.def.AbstractFlushingEventListener=FATAL 行を設定します。
<service name='persistence'
factory='org.jbpm.persistence.db.DbPersistenceServiceFactory' />
<service name='persistence'
factory='org.jbpm.persistence.db.DbPersistenceServiceFactory' />
重要
サービスに関する特定のプロパティーを記述する必要がある場合は、長い表記しか使用できません。
3.2. 設定プロパティー リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
- jbpm.byte.block.size
- 添付ファイルとバイナリー変数は、固定サイズのバイナリーオブジェクトリストの形式でデータベースに格納されます。(これの目的は、異なるデータベース間の移植性を向上させることです。これにより、jBPM をより簡単に埋め込むこともできます。) このパラメーターは、これらの固定長チャンクのサイズを制御します。
- jbpm.task.instance.factory
- タスクインスタンスの作成方法をカスタマイズするには、このプロパティーに対して完全修飾クラス名を指定します。(これは、
TaskInstanceBean をカスタマイズして新しいプロパティーを追加する場合に必要になることがよくあります。) 指定されたクラス名がorg.jbpm.taskmgmt.TaskInstanceFactoryインターフェイスを実装していることを確認してください。(詳細は、「 タスクインスタンスのカスタマイズ 」 を参照してください。) - jbpm.variable.resolver
- これを使用して、"JSF" ライクな式に含まれる最初の用語を jBPM が検索する方法をカスタマイズします。
- jbpm.class.loader
- このプロパティーを使用して jBPM クラスをロードします。
- jbpm.sub.process.async
- このプロパティーを使用して、サブプロセスの非同期シグナリングを許可します。
- jbpm.job.retries
- この設定は、失敗したジョブを破棄するタイミングを決定します。設定ファイルを確認すれば、そのようなジョブを破棄する前に指定した回数だけ処理を試行するようにエントリーを設定できます。
- jbpm.mail.from.address
- このプロパティーは、ジョブがどこから来たかを表示します。デフォルトは jbpm@noreply です。
3.3. その他の設定ファイル リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
jBPM には、カスタマイズ可能な多数の設定ファイルがあります。
hibernate.cfg.xml- これには、Hibernate マッピングリソースファイルへの参照と設定の詳細が含まれます。jBPM が使用する
hibernate.cfg.xmlファイルを変更するには、jbpm.cfg.xmlファイルで次のプロパティーを設定します。<string name="resource.hibernate.cfg.xml" value="new.hibernate.cfg.xml"/>jbpm.cfg.xml ファイルは、${soa.home}/jboss-as/server/${server.config}/jbpm.esb にあります。 org/jbpm/db/hibernate.queries.hbm.xml- このファイルには、jBPM セッション (
org.jbpm.db.*Session) で使用される Hibernate クエリーが含まれています。 org/jbpm/graph/node/node.types.xml- このファイルは、XML ノード要素を
Node実装クラスにマップするために使用されます。 org/jbpm/graph/action/action.types.xml- このファイルは、XML アクション要素を
Action実装クラスにマップするために使用されます。 org/jbpm/calendar/jbpm.business.calendar.properties- これには、"業務時間" と "自由時間" の定義が含まれています。
org/jbpm/context/exe/jbpm.varmapping.xml- これは、プロセス変数の値 (Java オブジェクト) を変数インスタンスに変換して jBPM データベースに保存する方法を指定します。
org/jbpm/db/hibernate/jbpm.converter.properties- これは、
id-to-classnameマッピングを指定します。id はデータベースに格納されます。org.jbpm.db.hibernate.ConverterEnumTypeクラスは、識別子をシングルトンオブジェクトにマップするために使用されます。 org/jbpm/graph/def/jbpm.default.modules.properties- これは、新しい
ProcessDefinitionにデフォルトで追加するモジュールを指定します。 org/jbpm/jpdl/par/jbpm.parsers.xml- これは、プロセスアーカイブ解析 のフェーズを指定します。
3.4. 楽観的な並行処理の例外のロギング リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
jBPM をクラスター設定で実行すると、jBPM は 楽観的ロック を使用してデータベースと同期します。これは、各操作をトランザクションで実行し、最後に競合が検出された場合、そのトランザクションをロールバックし、再試行して処理する必要があることを意味します。これにより、
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
.
org.hibernate.StateObjectStateException 例外が発生することがあります。これが発生した場合、Hibernate は単純なメッセージで例外をログに記録します。
optimistic locking
failed
optimistic locking
failed
Hibernate は、スタックトレース付きで
StateObjectStateException をログに記録することもできます。これらのスタックトレースを削除するには、org.hibernate.event.def.AbstractFlushingEventListener クラスを FATAL に設定します。次の設定を使用して、log4j でこれを行います。
log4j.logger.org.hibernate.event.def.AbstractFlushingEventListener=FATAL
log4j.logger.org.hibernate.event.def.AbstractFlushingEventListener=FATAL
jBPM スタックトレースをログに記録するには、パッケージのログカテゴリーのしきい値を ERROR より上に設定します。
3.5. オブジェクトファクトリー リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
オブジェクトファクトリー は、"Bean ライク" な XML 設定ファイルに含まれる仕様に合わせてオブジェクトを構築できます。このファイルは、完全なオブジェクトグラフを形成するためにオブジェクトを作成、設定、およびワイヤリングする方法を指示します。また、オブジェクトファクトリーを使用して、設定と他の Bean を単一の Bean に注入します。
以下の例に示すように、最も基本的な形式では、オブジェクトファクトリーはそのような設定から基本 型 と Java Bean の両方を作成できます。
このコードは、リストを設定する方法を示しています。
このコードは、マップを設定する方法を示しています。
ダイレクトフィールドインジェクション とプロパティーの
setter メソッドを使用して、Bean を設定します。
Bean を参照できます。参照されるオブジェクトは、Bean 自体である必要はありません。文字列や整数など、必要なものを参照できます。
<beans>
<bean name="a" class="org.jbpm.A" />
<ref name="b" bean="a" />
</beans>
<beans>
<bean name="a" class="org.jbpm.A" />
<ref name="b" bean="a" />
</beans>
次のコードが示すように、Bean は任意のコンストラクターで構築できます。
Bean は、
factory メソッドを使用して構築できます。
Bean は、クラスの
static factory メソッドを使用して構築できます。
属性
singleton="true" を使用して、名前付きの各オブジェクトを シングルトン としてマークします。そうすることで、特定の オブジェクトファクトリー が各リクエストに対して常に同じオブジェクトを返すようになります。
注記
シングルトン は、異なるオブジェクトファクトリー間で共有できません。
シングルトン 機能は、getObject と getNewObject というメソッドの区別を生み出します。通常は、getNewObject を使用する必要があります。これを使用すると、新しいオブジェクトグラフを構築する前に、オブジェクトファクトリー の オブジェクトキャッシュ がクリアされるためです。
オブジェクトグラフの構築時に、非シングルトンオブジェクト は、
オブジェクトファクトリー のキャッシュに格納されます。これにより、1 つのオブジェクトへの参照を共有できます。シングルトンオブジェクトキャッシュ は プレーンオブジェクトキャッシュ とは異なることに注意してください。シングルトン キャッシュは決してクリアされませんが、プレーンキャッシュは getNewObject メソッドが開始されるたびにクリアされます。
この章では、jBPM のさまざまな設定方法について詳しく説明しました。
第4章 永続性 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
この章では、Business Process Manager の "永続性" 機能について詳しく説明します。
ほとんどの場合、jBPM は複数のトランザクションにまたがるプロセスを実行するために使用されます。永続性 機能の主な目的は、待機状態 が発生したときにプロセスの実行を保存することです。プロセスの実行は、ステートマシン として考えると理解しやすくなります。その目的は、プロセス実行ステートマシンを、1 つのトランザクションの中で、ある状態から次の状態に移動させることです。
プロセス定義は、XML、Java オブジェクト、または jBPM データベースレコードの 3 つの異なる形式のいずれかで表すことができます。(また、ランタイムデータとログ情報は、Java オブジェクトまたは jBPM データベースレコードの形式で表すことができます。)
図4.1 変換とさまざまな形式
注記
プロセス定義とプロセスアーカイブの XML 表現の詳細は、14章 jBPM プロセス定義言語 を参照してください。
注記
プロセスアーカイブをデータベースにデプロイする方法の詳細は、「 プロセスアーカイブのデプロイ 」 を参照してください。
4.1. 永続性アプリケーションプログラミングインターフェイス リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
4.1.1. 設定フレームワークとの関係 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
永続性アプリケーションプログラミングインターフェイスは、設定フレームワークと統合されています (3章 設定 を参照)。 これは、
JbpmContext の convenience persistence メソッドの一部を公開し、jBPM の コンテキストブロック が永続性 API 操作を呼び出せるようにすることで実現されています。
4.1.2. JbpmContext の便利なメソッド リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
最も一般的に実行される 3 つの永続性操作は次のとおりです。
- プロセスデプロイメント
- 新しいプロセスの実行開始
- プロセスの実行継続
プロセスデプロイメント は通常、Graphical Process Designer または
deployprocess ant タスクから直接実行されます。ただし、Java から直接実行するには、次のコードを使用します。
新しいプロセス実行のインスタンス化の対象になるプロセス定義を指定して、新しいプロセス実行を作成します。これを行う最も一般的な方法は、プロセスの名前を参照することです。すると、jBPM はデータベース内でそのプロセスの最新バージョンを検索します。以下にデモコードを示します。
プロセスの実行を続行するには、データベースからプロセスインスタンス、トークン、または
taskInstance を取得し、POJO (Plain Old Java Object) jBPM オブジェクトでいくつかのメソッドを呼び出します。さrない、processInstance に加えられた更新をデータベースに保存します。
ForUpdate メソッドを JbpmContext クラスで使用する場合、jbpmContext.save メソッドを明示的に呼び出す必要はないことに注意してください。これは、jbpmContext クラスが閉じられると、保存プロセスが自動的に実行されるためです。たとえば、taskInstance が完了したことを jBPM に通知したい場合があります。これにより実行の継続が引き起こされることがあるため、taskInstance に関連する processInstance を保存する必要があります。これを行う最も便利な方法は、loadTaskInstanceForUpdate メソッドを使用することです。
重要
以下の説明を読み、jBPM による永続性機能の管理方法と Hibernate の機能の使用方法を確認してください。
JbpmConfiguration は、一連の ServiceFactories を維持します。これらは jbpm.cfg.xml ファイルを介して設定され、必要に応じてインスタンス化されます。
DbPersistenceServiceFactory は、最初に必要になったときにのみインスタンス化されます。その後、ServiceFactory は JbpmConfiguration で維持されます。
DbPersistenceServiceFactory は Hibernate ServiceFactory を管理しますが、これは最初に要求されたときにのみインスタンス化されます。
DbPersistenceServiceFactory パラメーター:
isTransactionEnabledsessionFactoryJndiNamedataSourceJndiNameisCurrentSessionEnabled
図4.2 永続性関連のクラス
jbpmConfiguration.createJbpmContext () クラスが呼び出されると、JbpmContext のみが作成されます。この時点では、それ以上の永続性関連の初期化は行われません。JbpmContext は、DbPersistenceService クラスを管理します。このクラスは、最初に要求されたときにインスタンス化されます。DbPersistenceService クラスは、Hibernate セッションを管理します。これも、最初に必要になったときにのみインスタンス化されます。(つまり、Hibernate セッションは、永続性を必要とする最初の操作が呼び出されたときにのみ開かれます。)
4.2. 永続性サービスの設定 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
4.2.1. DbPersistenceServiceFactory リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
DbPersistenceServiceFactory クラスには、さらに isTransactionEnabled、sessionFactoryJndiName、および dataSourceJndiName という 3 つの設定プロパティーがあります。jbpm.cfg.xml ファイルでこれらのプロパティーを指定するには、factory 要素内で Bean として Service Factory を指定します。このサンプルコードは、その方法を示しています。
重要
ファクトリーを設定する際に、短い表記と長い表記を混在させないでください。(「 ファクトリーのカスタマイズ 」 も併せて参照してください。) ファクトリーがクラスの単なる新しいインスタンスである場合は、ファクトリー属性を使用してそのファクトリークラス名を参照します。一方、ファクトリーのプロパティーに設定が必要な場合は、長い表記を使用する必要があり、ファクトリーと Bean をネストされた要素として組み合わせる必要があります。
isTransactionEnabled- デフォルトでは、jBPM はセッションが初めて取得されたときに Hibernate トランザクションを開始します。
jbpmContextが閉じられると、Hibernate トランザクションは終了します。その後、jbpmContext.setRollbackOnlyが呼び出されたかどうかに応じて、トランザクションはコミットまたはロールバックされます。(isRollbackOnly プロパティーはTxServiceで維持されます。) トランザクションを無効にし、jBPM が Hibernate でそれらを管理するのを禁止するには、isTransactionEnabled プロパティー値をfalseに設定します。(このプロパティーはjbpmContextの動作のみを制御します。DbPersistenceService.beginTransaction()は、isTransactionEnabled 設定を無視するアプリケーションプログラミングインターフェイスを使用して直接呼び出すことができます。) トランザクションの詳細は、「 Hibernate トランザクション 」 を参照してください。 sessionFactoryJndiName- デフォルトでは、これは
nullです。これは、セッションファクトリーが JNDI から取得されないことを意味します。このプロパティーが設定されていて、Hibernate セッションを作成するためにセッションファクトリーが必要な場合は、JNDI から取得されます。 dataSourceJndiName- デフォルトでは、これは
nullです。その結果、JDBC 接続が作成され、Hibernate に委譲されます。データソースを指定すると、Business Process Manager は新しいセッションを開くとともに、データソースから JDBC 接続を取得し、それを Hibernate に提供します。
4.2.1.1. Hibernate セッションファクトリー リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
デフォルトでは、
DbPersistenceServiceFactory はクラスパスのルートにある hibernate.cfg.xml ファイルを使用して、Hibernate セッションファクトリーを作成します。Hibernate 設定ファイルのリソースが jbpm.hibernate.cfg.xml にマップされていることに注意してください。これは、jbpm.cfg.xml を再設定してカスタマイズします。
重要
resource.hibernate.properties が指定されている場合、そのリソースファイルのプロパティーは、
hibernate.cfg.xml のすべてのプロパティーを上書きします。データベースを参照するように hibernate.cfg.xml を更新するのではなく、hibernate.properties を使用して jBPM のアップグレードを処理してください。そうすることで、変更を再適用することなく hibernate.cfg.xml ファイルをコピーできます。
4.2.1.2. C3PO 接続プールの設定 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
http://www.hibernate.org/214.html で Hibernate のドキュメントを参照してください。
4.2.1.3. ehCache プロバイダーの設定 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
JBossCache を使用して jBPM を設定する方法については、http://wiki.jboss.org/wiki/Wiki.jsp?page=JbpmConfiguration を参照してください。
Hibernate と連携するようにキャッシュプロバイダーを設定する方法については、http://www.hibernate.org/hib_docs/reference/en/html/performance.html#performance-cache を参照してください。
jBPM に付属する
hibernate.cfg.xml ファイルには、次の行が含まれています。
<property name="hibernate.cache.provider_class">
org.hibernate.cache.HashtableCacheProvider
</property>
<property name="hibernate.cache.provider_class">
org.hibernate.cache.HashtableCacheProvider
</property>
これは、ユーザーがクラスパスの設定を気にする必要がないように提供されています。
警告
Hibernate の
HashtableCacheProvider を実稼働環境で使用しないでください。
HashtableCacheProvider の代わりに ehcache を使用するには、関連する行をクラスパスから削除し、代わりに ehcache.jar を使用します。お使いの環境と互換性のある正しい ehcache ライブラリーバージョンの検索が必要になる場合があることに注意してください。
4.2.2. Hibernate トランザクション リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
デフォルトでは、jBPM は "トランザクションごとのセッション" パターンを使用してトランザクションを Hibernate に委譲します。
jbpmContext で永続的な操作が呼び出されたときに初めてセッションが開かれると、jBPM は Hibernate トランザクションを開始します。トランザクションは、Hibernate セッションが閉じられる直前にコミットされます。これは jbpmContext.close() 内で実行されます。
jbpmContext.setRollbackOnly() を使用して、ロールバック対象のトランザクションをマークします。そうすることで、セッションが jbpmContext.close() メソッド内で閉じられる直前にトランザクションがロールバックされます。
Business Process Manager が Hibernate アプリケーションプログラミングインターフェイスを介してトランザクションメソッドを呼び出すことを禁止するには、isTransactionEnabled プロパティーを
false に設定します。これについては、「DbPersistenceServiceFactory」 で詳しく説明しています。
4.2.3. JTA トランザクション リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
マネージドトランザクションは、jBPM が JBoss Application Server で使用されている場合に最もよく見られます。次のコードサンプルは、トランザクションを JTA にバインドする一般的な方法を示しています。
次に、データソースを使用するように Hibernate セッションファクトリーを設定して、Hibernate 自体を Transaction Manager にバインドします。複数のデータソースを使用する場合は、それらのデータベースを
XA datasource にバインドします。
注記
Hibernate を Transaction Manager にバインドする方法の詳細は、http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#configuration-optional-transactionstrategy を参照してください。
次に、
XA datasource を使用するように Hibernate を設定します。
これらの設定により、エンタープライズ Bean が CMT を使用できるようになり、Web コンソールが BMT を使用できるようになります。(jta.UserTransaction も指定されているのはそのためです。)
4.2.4. クエリーのカスタマイズ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
jBPM が使用するすべての SQL クエリーは、1 つの中央設定ファイルにあります。このリソースファイルは、
hibernate.cfg.xml 設定ファイルで参照されます。
<hibernate-configuration>
<!-- hql queries and type defs -->
<mapping resource="org/jbpm/db/hibernate.queries.hbm.xml" />
</hibernate-configuration>
<hibernate-configuration>
<!-- hql queries and type defs -->
<mapping resource="org/jbpm/db/hibernate.queries.hbm.xml" />
</hibernate-configuration>
これらのクエリーの 1 つ以上をカスタマイズするには、元のファイルのバックアップを作成します。次に、カスタマイズしたバージョンをクラスパスの任意の場所に配置し、カスタマイズしたバージョンを参照するように
hibernate.cfg.xml の org/jbpm/db/hibernate.queries.hbm.xml への参照を更新します。
4.2.5. データベースの互換性 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
jBPM は、Hibernate でサポートされているすべてのデータベースで実行されます。
4.2.5.1. JDBC 接続の分離レベル リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
JDBC 接続のデータベース分離レベルを少なくとも
READ_COMMITTED に設定します。
警告
READ_UNCOMMITTED (分離レベルゼロ、Hypersonic でサポートされる唯一の分離レベル) に設定されている場合、ジョブエグゼキューター で競合状態が発生する可能性があります。これは、複数のトークンの同期が行われているときにも発生する可能性があります。
4.2.5.2. データベースの変更 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
別のデータベースを使用するように Business Process Manger を再設定するには、次の手順に従います。
- JDBC ドライバーライブラリーアーカイブをクラスパスに配置します。
- jBPM が使用する Hibernate 設定を更新します。
- 新しいデータベースにスキーマを作成します。
4.2.5.3. データベーススキーマ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
jbpm.db サブプロジェクトには、ユーザーが選択したデータベースの使用を開始するのに役立つドライバー、手順、およびスクリプトが含まれています。詳細は、jbpm.db プロジェクトのルートにある readme.html を参照してください。
注記
JBPM は任意のデータベースの DDL スクリプトを生成できますが、これらのスキーマは常に効率的であるとは限りません。会社のデータベース管理者に生成された DDL を確認してもらい、列の型とインデックスを最適化できるようにすることを検討してください。
次の Hibernate 設定オプションは、開発環境で使用できます。hibernate.hbm2ddl.auto を
create-drop に設定すると、データベースがアプリケーションで初めて使用されるときに、スキーマが自動的に作成されます。アプリケーションが終了すると、スキーマは削除されます。
4.2.5.3.1. プログラムによるデータベーススキーマ操作 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
jBPM は、
org.jbpm.JbpmConfiguration のメソッド createSchema および dropSchema を介して、データベーススキーマを作成および削除するための API を提供します。これらのメソッドの呼び出しには、設定されたデータベースユーザーの権限以外に制約がないことに注意してください。
注記
前述の API は、クラス
org.jbpm.db.JbpmSchema によって提供される、より広範な機能へのファサードを構成します。
4.2.5.4. Hibernate クラスの組み合わせ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
Hibernate と jBPM の永続クラスを組み合わせると、2 つの大きなメリットが得られます。セッション、接続、およびトランザクションの管理が容易になります。これは、これらを 1 つの Hibernate セッションファクトリーに結合することで、Hibernate セッションと JDBC 接続が 1 つだけになるためです。したがって、jBPM の更新は、ドメインモデルの更新と同じトランザクションになります。これにより、Transaction Manager が不要になります。
第 2 に、Hibernate 永続オブジェクトを追加作業なしでプロセス変数にドロップできます。
これを実現するには、中央の
hibernate.cfg.xml ファイルを 1 つ作成します。デフォルトの jBPM hibernate.cfg.xml を出発点として使用し、独自の Hibernate マッピングファイルへの参照を追加してカスタマイズするのが最も簡単です。
4.2.5.5. jBPM Hibernate マッピングファイルのカスタマイズ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
次の手順に従って、jBPM Hibernate マッピングファイルをカスタマイズします。
- ソース (
src/jbpm-jpdl-sources.jar) から jBPM Hibernate マッピングファイルをコピーします。 - コピーをクラスパスの任意の場所に配置します (以前と同じ場所でないことを確認します)。
hibernate.cfg.xml内のカスタマイズしたマッピングファイルへの参照を更新します。
4.2.5.6. 2 次キャッシュ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
jBPM は Hibernate の 二次キャッシュ を使用して、一度ロードされたプロセス定義をメモリーに保持します。プロセス定義のクラスとコレクションは、キャッシュ要素が次のようになるように、Hibernate マッピングファイルで設定されます。
<cache usage="nonstrict-read-write"/>
<cache usage="nonstrict-read-write"/>
プロセス定義は決して変更されないため、2 次キャッシュに保持しても問題ありません。(「 デプロイされたプロセス定義の変更 」 も併せて参照してください。)
デフォルトのキャッシュストラテジーは、
nonstrict-read-write に設定されています。ランタイム実行時に、プロセス定義が静的なままとなるため、最大限のキャッシュを実現できます。理論的には、read-only キャッシュストラテジーのほうがランタイム実行にはさらに適していますが、その設定では新しいプロセス定義のデプロイメントが許可されません。
この章では、Hibernate を最大限に活用する方法など、jBPM の永続性のトピックに関連する多くの理論的情報と実践的なアドバイスを説明しました。
第5章 Java EE アプリケーションサーバーの機能 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
この章でが、jBPM が提供する、Java EE インフラストラクチャーを活用するために使用できる機能を説明します。
5.1. エンタープライズ Bean リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
CommandServiceBean は ステートレスセッション Bean であり、別の jBPM コンテキスト内の execute メソッドを呼び出すことにより、Business Process Manager コマンドを実行します。使用可能な環境エントリーとカスタマイズ可能なリソースを次の表にまとめます。
| 名前 | タイプ | 説明 |
|---|---|---|
JbpmCfgResource | 環境エントリー | これは、jBPM 設定の読み取り元となるクラスパスリソースです。オプションであり、デフォルトは jbpm.cfg.xml です。 |
ejb/TimerEntityBean | EJB 参照 | これは、スケジューラーサービスを実装するローカルエンティティー Bean へのリンクです。タイマーを含むプロセスに必要です。 |
jdbc/JbpmDataSource | リソースマネージャー参照 | これは、jBPM 永続性サービスへの JDBC 接続を提供するデータソースの論理名です。Hibernate 設定ファイルの hibernate.connection.datasource プロパティーと一致する必要があります。 |
jms/JbpmConnectionFactory | リソースマネージャー参照 | これは、JMS 接続を jBPM メッセージサービスに提供するファクトリーの論理名です。非同期継続を含むプロセスに必要です。 |
jms/JobQueue | メッセージ宛先参照 | jBPM メッセージサービスは、ジョブメッセージをこのキューに送信します。ジョブリスナー Bean のメッセージ受信元のキューとこのキューが必ず同じになるように、message-destination-link は共通の論理宛先である JobQueue を参照します。 |
jms/CommandQueue | メッセージ宛先参照 | コマンドリスナー Bean は、このキューからメッセージを受信します。コマンドメッセージ送信先のキューとこのキューが必ず同じになるように、message-destination-link 要素は共通の論理宛先である CommandQueue を参照します。 |
CommandListenerBean は、コマンドメッセージの CommandQueue をリッスンするメッセージ駆動型 Bean です。この Bean は、コマンドの実行を CommandServiceBean に委譲します。
メッセージの本文は、
org.jbpm.Command インターフェイスを実装できる Java オブジェクトでなければなりません。(メッセージプロパティーがある場合は無視されます。) メッセージが想定される形式でない場合、メッセージは DeadLetterQueue に転送され、それ以上処理されません。宛先参照が存在しない場合も、メッセージは拒否されます。
受信したメッセージで宛先
replyTo が指定されている場合、コマンド実行結果が オブジェクトメッセージ にラップされて送信されます。
コマンド接続ファクトリー環境参照 は、Java Message Service 接続を提供するために使用されるリソースマネージャーを参照します。
逆に、
JobListenerBean は、非同期継続 をサポートするために、ジョブメッセージの JbpmJobQueue をリッスンするメッセージ駆動型 Bean です。
注記
メッセージには、
long 型の jobId というプロパティーが必要であることに注意してください。このプロパティには、データベース内にある保留中の Job への参照が含まれている必要があります。メッセージ本文が存在する場合、それは無視されます。
この Bean は
CommandListenerBean を拡張します。後者の環境エントリーとカスタマイズ可能なそのリソース参照を継承します。
| 名前 | タイプ | 説明 |
|---|---|---|
ejb/LocalCommandServiceBean | EJB 参照 | これは、別の jBPM コンテキストでコマンドを実行するローカルセッション Bean へのリンクです。 |
jms/JbpmConnectionFactory | リソースマネージャー参照 | これは、結果メッセージを生成するための Java Message Service 接続を提供するファクトリーの論理名です。返信先を示すコマンドメッセージに必要です。 |
jms/DeadLetterQueue | メッセージ宛先参照 | コマンドを含まないメッセージは、ここで参照されているキューに送信されます。これはオプションです。これがない場合、そのようなメッセージは拒否され、コンテナーが再配信されることがあります。 |
| - | ||
| メッセージ宛先参照 | コマンドを含まないメッセージは、ここで参照されているキューに送信されます。これがない場合、そのようなメッセージは拒否され、コンテナーが再配信されることがあります。 |
TimerEntityBean は、Enterprise Java Bean タイマーサービス でスケジューリングに使用されます。Bean の有効期限が切れると、タイマーの実行が command service Bean に委譲されます。
TimerEntityBean は、Business Process Manager のデータソースへのアクセスを必要とします。Enterprise Java Bean デプロイメント記述子は、エンティティー Bean をデータベースにマップする方法を定義しません。(これはコンテナー提供者に任されています。) JBoss Application Server では、jbosscmp-jdbc.xml 記述子が、データソースの JNDI 名とリレーショナルマッピングデータ (テーブル名や列名など) を定義します。
注記
JBoss CMP (コンテナー管理永続性) 記述子は、リソースマネージャー参照 (
java:comp/env/jdbc/JbpmDataSource) とは異なり、グローバル JNDI 名 (java:JbpmDS) を使用します。
注記
以前のバージョンの Business Process Manager は、
TimerServiceBean というステートレスセッション Bean を使用して、Enterprise Java Bean タイマーサービスと対話していました。セッション方式は、cancelation メソッドのボトルネックが避けられなかったため、断念せざるを得ませんでした。セッション Bean には ID がないため、タイマーサービスは すべて のタイマーをイテレートして、キャンセルする必要のあるタイマーを見つける必要がありました。
この Bean は、下位互換性を確保する目的で引き続き使用できます。
TimerEntityBean と同じ環境で動作するため、移行が容易です。
| 名前 | タイプ | 説明 |
|---|---|---|
ejb/LocalCommandServiceBean | EJB 参照 | これは、別の jBPM コンテキストでタイマーを実行するローカルセッション Bean へのリンクです。 |
5.2. jBPM エンタープライズ設定 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
次の設定項目が
jbpm.cfg.xml に含まれています。
JtaDbPersistenceServiceFactory により、Business Process Manager は JTA トランザクションに参加できます。既存のトランザクションが進行中の場合、JTA 永続性サービスはそれを "保持" します。そうでない場合は、新しいトランザクションを開始します。Business Process Manager のエンタープライズ Bean は、トランザクション管理をコンテナーに委譲するように設定されています。ただし、トランザクションがアクティブでない環境 (Web アプリケーションなど) で JbpmContext を作成すると、新しいトランザクションが自動的に開始されます。 JTA 永続性サービスファクトリー には、以下で説明する設定可能なフィールドが含まれています。
- isCurrentSessionEnabled
- これを
trueに設定すると、Business Process Manager は、進行中の JTA トランザクションに関連付けられた "現在" の Hibernate セッションを使用します。これはデフォルト設定です。詳細は、http://www.hibernate.org/hib_docs/v3/reference/en/html/architecture.html#architecture-current-session を参照してください。コンテキストセッションメカニズムを利用して、アプリケーションの他の部分で jBPM と同じセッションを使用します。これは、SessionFactory.getCurrentSession()の呼び出しを通じて行われます。または、isCurrentSessionEnabled をfalseに設定し、JbpmContext.setSession(session)メソッドを介してセッションを注入することで、jBPM に Hibernate セッションを提供します。これにより、jBPM がアプリケーションの他の部分と同じ Hibernate セッションを使用することも保証されます。注記Hibernate セッションは (永続性コンテキストなどを介して) ステートレスセッション Bean に注入できます。 - isTransactionEnabled
trueに設定すると、jBPM は Hibernate のtransaction APIを介してトランザクションを開始し、JbpmConfiguration.createJbpmContext()メソッドを使用してトランザクションをコミットします。(JbpmContext.close()が呼び出されると、Hibernate セッションは閉じられます。)警告これは、Business Process Manager が EAR としてデプロイされている場合に望ましい動作ではないため、isTransactionEnabled はデフォルトではfalseに設定されています。(詳細は、http://www.hibernate.org/hib_docs/v3/reference/en/html/transactions.html#transactions-demarcation を参照してください。)
JmsMessageServiceFactory は、 Java Message Service インターフェイスを通じて公開される信頼性の高い通信インフラストラクチャーを利用して、非同期継続メッセージ を JobListenerBean に配信します。JmsMessageServiceFactory は、次の設定可能なフィールドを公開します。
- connectionFactoryJndiName
- これは、JNDI 初期コンテキストでの JMS 接続ファクトリーの名前です。デフォルトは
java:comp/env/jms/JbpmConnectionFactoryです。 - destinationJndiName
- これは、ジョブメッセージ送信先の JMS 宛先の名前です。これは、
JobListenerBeanがメッセージを受信する宛先と一致する必要があります。デフォルトはjava:comp/env/jms/JobQueueです。 - isCommitEnabled
- これは、Business Process Manager が
JbpmContext.close()で Java Message Service セッションをコミットする必要があるかどうかを指定します。JMS メッセージサービスによって生成されたメッセージは、現在のトランザクションがコミットされる前に受信されることを意図したものではありません。そのため、このサービスによって作成されたセッションは、常にトランザクション処理されます。デフォルト値はfalseです。これは、使用中の接続ファクトリーが XA 対応である場合に適しています。Java Message Service セッションによって生成されるメッセージは、JTA トランザクション全体によって制御されるためです。JMS 接続ファクトリーが XA 対応でない場合は、Business Process Manager が JMS セッションのローカルトランザクションを明示的にコミットするように、このフィールドをtrueに設定する必要があります。
EntitySchedulerServiceFactory は、ビジネスプロセスタイマーをスケジュールするために使用されます。これは、Enterprise Java Bean コンテナーによって提供される時間指定イベントのトランザクション通知サービスに基づいて構築することによって行われます。EJB スケジューラーサービスファクトリー には、以下で説明する設定可能なフィールドがあります。
- timerEntityHomeJndiName
- これは、JNDI 初期コンテキストでの
TimerEntityBeanのローカルホームインターフェイスの名前です。デフォルト値はjava:comp/env/ejb/TimerEntityBeanです。
5.3. Hibernate エンタープライズ設定 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
hibernate.cfg.xml ファイルには、次の設定項目が含まれています。他のデータベースまたはアプリケーションサーバーをサポートするには、これらを変更します。
hibernate.dialect 設定は、お使いのデータベース管理システムに適した設定に置き換えます。(詳細は、http://www.hibernate.org/hib_docs/v3/reference/en/html/session-configuration.html#configuration-optional-dialects を参照してください。)
HashtableCacheProvider は、サポートされている他のキャッシュプロバイダーに置き換えることができます。(詳細は、http://www.hibernate.org/hib_docs/v3/reference/en/html/performance.html#performance-cache を参照してください。)
初期状態で、jBPM は
JTATransactionFactory を使用するように設定されています。既存のトランザクションが進行中の場合、JTA トランザクションファクトリーはそれを使用します。それ以外の場合は、新しいトランザクションが作成されます。jBPM のエンタープライズ Bean は、トランザクション管理をコンテナーに委譲するように設定されています。ただし、アクティブなトランザクションがないコンテキスト (Web アプリケーションなど) で jBPM API が使用されている場合、トランザクションが自動的に開始されます。
コンテナー管理トランザクション を使用するときに意図しないトランザクションが作成されるのを防ぐには、
CMTTransactionFactory に切り替えます。この設定により、Hibernate が常に既存のトランザクションを探し、見つからない場合は問題を報告するようになります。
5.4. クライアントコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
エンタープライズサービスを活用できる Business Process Manager API に対して直接記述されたクライアントコンポーネントのデプロイメント記述子に対して、適切な環境参照が設定されていることを確認してください。以下の記述子は、クライアントセッション Bean の典型的なものと見なすことができます。
上記の環境参照は、次のようにターゲット運用環境のリソースにバインドできます。JNDI 名は、Business Process Manager エンタープライズ Bean で使用される値と一致することに注意してください。
クライアントコンポーネントがエンタープライズ Bean ではなく Web アプリケーションである場合、デプロイメント記述子は次のようになります。
上記の環境参照は、次のコードサンプルのとおり、ターゲット運用環境のリソースにバインドすることもできます。
5.5. まとめ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
この章では、Java EE インフラストラクチャーを活用するために使用できる jBPM によって提供される機能を詳しく説明しました。本章の説明をもとに、お客様の企業環境でこれらをテストすることをお勧めします。
第6章 プロセスモデリング リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
6.1. 役に立つ定義 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
このセクションでは、このガイドの他の章で使用されている用語について説明します。
プロセス定義 は、ビジネスプロセスの正式な仕様を表すものであり、有向グラフ に基づいています。グラフは、ノードと遷移で構成されます。グラフ内のすべてのノードは、特定のタイプのノードです。ノードタイプはランタイムの動作を定義します。プロセス定義には、開始状態が 1 つしかありません。
トークン は、実行の 1 つのパスです。トークンは、グラフ内のノードへのポインターを保持するランタイムの概念です。
プロセスインスタンス は、プロセス定義の 1 つの実行です。プロセスインスタンスが作成されると、実行のメインパスに対してトークンが生成されます。このトークンはプロセスインスタンスの ルートトークン と呼ばれ、プロセス定義の 開始状態 に配置されます。
シグナルは、トークンにグラフ実行を続行するように指示します。トークンは名前のないシグナルを受信すると、デフォルトの 退出遷移 を介して現在のノードから退出します。シグナルで transition-name が指定されている場合、トークンは指定された遷移を介してそのノードから退出します。プロセスインスタンスに与えられたシグナルは、ルートトークンに委譲されます。
トークンがノードに進入すると、ノードが実行されます。ノード自体は、グラフ実行を継続させる役割があります。グラフ実行の継続は、トークンをノードから退出させることで実現されます。各タイプのノードは、グラフ実行の継続のために異なる動作を実装できます。実行を渡さないノードは 状態 として動作します。
アクション は、プロセス実行中にイベントで実行される Java コードの一部です。グラフ は、ソフトウェア要件の伝達において重要な手段ですが、作成中のソフトウェアの 1 つのビュー (プロジェクション) にすぎません。多くの技術的な詳細は、そこには表示されません。アクションは、グラフィカルな表現以外の技術的な詳細を追加するために使用されるメカニズムです。グラフを配置したら、アクションで装飾することができます。主な イベントタイプ は、
ノード進入、ノード退出、遷移取得 です。
これらの定義を理解したら、次に進み、プロセスモデリングの仕組みを確認してください。
6.2. プロセスグラフ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プロセス定義は、ノードと遷移で構成されるグラフです。この情報は XML で表現され、
processdefinition.xml というファイルにあります。各ノードには タイプ が必要です (状態、決定、フォーク、および ジョイン など)。 各ノードには、一連の 退出遷移 があります。ノードから退出する遷移には、それらを区別するために名前を付けることができます。たとえば、次の図は、オークションプロセスのプロセスグラフを示しています。
図6.1 オークションプロセスのグラフ
以下は、同じオークションプロセスを XML で表したプロセスグラフです。
6.3. ノード リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プロセスグラフは、ノードと遷移で構成されます。各ノードは特定のタイプのノードです。ノードタイプにより、ランタイム時にノードに実行が到達したときの動作が決定されます。Business Process Manager は、使用する一連のノードタイプを提供します。または、カスタムコードを記述して、特定のノードの動作を実装することもできます。
6.3.1. ノードの役割 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
各ノードには 2 つの主な役割があります。まず、ノードはプレーンな Java コードを実行できます。このコードは、通常はノードの機能に関連するものです。2 番目の役割は、プロセスの実行を渡すことです。
ノードは、プロセスの実行を渡そうとするときに、次の選択肢に直面することがあります。ノードは最も適切なコースに従います。
- 実行を伝播できない。(ノードは
待機状態として動作します。) - ノードの
退出遷移の 1 つを介して実行を伝播できる。(これは、最初にノードに到達したトークンが、API 呼び出しexecutionContext.leaveNode(String)により退出遷移の 1 つを介して渡されることを意味します。) ノードは、いくつかのカスタムプログラミングロジックを実行し、待機せずにプロセスの実行を自動的に続行するという意味で、自動的に動作します。 - 新しいトークンの作成を "決定" できる。新しい各トークンは、新しい実行パスを表します。これらの新しいトークンはそれぞれ、ノードの
退出遷移を介して起動できます。この種の動作の良い例はフォークノードです。 - 実行パスを終了できる。これは、トークンが終了したことを意味します。
- プロセスインスタンスの ランタイム構造 全体を変更できる。ランタイム構造は、トークンのツリーを含むプロセスインスタンスであり、それぞれが実行パスを表します。ノードは、トークンを作成および終了し、各トークンをグラフのノードに配置し、遷移を介してトークンを起動できます。
Business Process Manager には、事前に実装された一連のノードタイプが含まれており、それぞれに特定の設定と動作があります。ただし、独自のノード動作を記述してプロセスで使用することもできます。
6.3.2. ノードタイプ: タスクノード リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
タスクノード は、手動で実行する必要がある 1 つ以上のタスクを表します。そのため、実行プロセスがノードに到達すると、ワークフロー参加者に属するリストにタスクインスタンスが作成されます。その後、ノードは
待機状態 に入ります。ユーザーがタスクを完了すると、実行がトリガーされて再開されます。
6.3.3. ノードタイプ: 状態 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
状態 は "必要最小限" の
待機状態 です。これは、どのタスクリストに対してもタスクインスタンスが作成されないという点で、タスクノードとは異なります。これは、プロセスが外部システムを待機している場合に役立ちます。その後、プロセスは待機状態になります。外部システムが応答メッセージを送信すると、通常 token.signal() が呼び出され、プロセス実行の再開をトリガーします。
6.3.4. ノードタイプ: 決定 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
決定をモデル化する方法は 2 つあります。どちらを使用するかは、ユーザーの裁量に任されています。オプションは次のとおりです。
- プロセスによって決定を行う。そのため、決定をプロセス定義で指定する。
- 外部エンティティーによって決定を行う。
プロセスによって決定を行う場合は、
決定ノード を使用します。2 つの方法のいずれかで決定基準を指定します。最も簡単な方法は、条件要素を遷移に追加することです。(条件は、ブール値を返す EL 式または Beanshell スクリプトです。)
ランタイム時に、決定ノードは、条件が指定されている
退出遷移 をループします。決定ノードは、XML で指定された順序でこれらの遷移を最初に評価します。条件が true に解決される最初の遷移が取得されます。すべての遷移の条件が false に解決された場合、デフォルトの遷移 (XML の最初の遷移) が代わりに取得されます。デフォルトの遷移が見つからない場合、JbpmException が出力されます。
2 つ目の方法は、取得する遷移の名前を返す式を使用することです。expression 属性を使用して、決定の式を指定します。この式は、決定ノードのいずれかの
退出遷移 に解決する必要があります。
また、決定で handler 要素を使用することもできます。この要素を使用すると、決定ノードで指定できる
DecisionHandler インターフェイスを実装できます。このシナリオでは、決定は Java クラスによって計算され、選択された 退出遷移 が DecisionHandler 実装に属する decide メソッドによって返されます。
外部エンティティーによって決定を行う場合は、
状態 または 待機状態 ノードから退出する複数の遷移を常に使用してください。待機状態 が完了した後に実行を再開する外部トリガーで退出遷移を指定できます (Token.signal(String transitionName) や TaskInstance.end(String transitionName) など)。
6.3.5. ノードタイプ: フォーク リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
フォークは、単一の実行パスを複数の同時実行パスに分割します。デフォルトでは、フォークは、そこから退出する遷移ごとに子トークンを作成します (これにより、フォークに到達するトークン間に親子関係が作成されます)。
6.3.6. ノードタイプ: ジョイン リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
デフォルトでは、ジョインは、その内部に到達したすべてのトークンが同じ親の子であると想定します。(この状況は、上記のようにフォークを使用した場合、およびフォークによって作成されたすべてのトークンが同じジョインに到達した場合に発生します。)
ジョインは、それに進入するすべてのトークンを終了します。次に、それらのトークンの親子関係を調べます。すべての兄弟トークンがジョインに到達すると、親トークンは
退出遷移 に渡されます。アクティブな兄弟トークンがまだある場合、ジョインは 待機状態 として動作します。
6.3.7. ノードタイプ: ノード リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
このノードは、カスタムコードの作成を回避するために使用します。このノードには、1 つのサブ要素アクションのみが必要です。サブ要素アクションは、実行がノードに到達したときに実行されます。
actionhandler に記述されたカスタムコードは、任意の処理を実行できますが、実行を渡す役割もあることに注意してください。詳細は、「 ノードの役割 」 を参照してください。
このノードは、Java API を利用して企業のビジネスアナリスト向けの機能ロジックを実装する場合にも使用できます。そのようにすると、ノードがプロセスのグラフィカル表現に表示されたままになるため、便利です。(プロセスのグラフィカル表現には表示されないコードを追加するには、アクションを使用します。)
6.4. 遷移 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
遷移には、ソースノードと宛先ノードの両方があります。ソースノードは、from プロパティー、宛先ノードは to プロパティーによって表されます。
必要に応じて、遷移に名前を付けることができます。(Business Process Manager のほとんどの機能は、遷移に固有の名前が付けられていることに依存しています。) 複数の遷移が同じ名前の場合、最初の遷移が取得されます。(ノードで遷移名が重複する場合、
Map getLeavingTransitionsMap() メソッドは、List getLeavingTransitions() よりも少ない要素を返します。)
6.5. アクション リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
アクションは、プロセス実行中にイベントで実行される Java コードの一部です。グラフは、ソフトウェア要件の伝達において重要な手段です。しかし、グラフは作成中のソフトウェアの 1 つのビュー (プロジェクション) にすぎません。多くの技術的な詳細は、そこには表示されません。アクションは、グラフィカルな表現以外の技術的な詳細を追加するためのメカニズムです。グラフを配置したら、アクションで装飾することができます。これにより、グラフの構造を変更せずに Java コードをグラフに関連付けることができます。主なイベントタイプは、ノード進入、ノード退出、遷移取得です。
重要
イベントに配置されるアクションとノードに配置されるアクションには違いがあります。イベントに配置されたアクションは、イベントが発生したときに実行されます。このアクションには、プロセスの制御の流れに影響を与える方法はありません。(これは、オブザーバーパターン に似ています。) 対照的に、ノードに配置されたアクションには、実行を渡す役割があります。
このセクションでは、イベントに対するアクションの例を説明します。この例は、特定の遷移でデータベースの更新を行う方法を示しています。(データベースの更新は技術的には重要ですが、ビジネスアナリストにとっては重要ではありません。)
図6.2 データベース更新アクション
6.5.1. アクションリファレンス リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
アクションには名前を付けることができます。これにより、アクションが指定されている他の場所からアクションを参照できます。名前付きアクションは、子要素 としてプロセス定義に追加することもできます。
この機能を使用して、アクション設定の重複を制限します。(これは、アクションの設定が複雑な場合や、ランタイムアクションをスケジュールまたは実行する必要がある場合に特に役立ちます。)
6.5.2. イベント リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
イベントは、プロセスの実行における特定の瞬間です。Business Process Manager のエンジンは、グラフ実行 中にイベントを "発生" させます。これは、ソフトウェアが次の状態を計算するとき (つまり、シグナルを処理するとき) に行われます。 イベントは常に、プロセス定義内の要素に関連しています。
ほとんどのプロセス要素は、さまざまなタイプのイベントを起動することができます。たとえば、ノードは
node-enter イベントと node-leave イベントの両方を発生させることができます。(イベントはアクションの "フック" です。各イベントにはアクションのリストがあります。jBPM エンジンがイベントを発生させると、アクションのリストが実行されます。)
6.5.3. イベントの受け渡し リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
スーパーステート は、プロセス定義の要素に親子関係を作成します。(スーパーステートに含まれるノードと遷移は、そのスーパーステートを親として持ちます。最上位の要素はプロセス定義を親として持ち、プロセス定義自体はそれより上の親を持ちません。) イベントが発生すると、イベントは親階層に渡されます。これにより、プロセス内のすべての遷移イベントをキャプチャーし、一元化された場所を介してアクションをこれらのイベントに関連付けることができます。
6.5.4. スクリプト リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
スクリプト は、Beanshell スクリプトを実行するアクションです。(Beanshell の詳細は、http://www.beanshell.org/ を参照してください。) デフォルトでは、すべてのプロセス変数をスクリプト変数として使用できますが、スクリプト変数はプロセス変数に書き込まれません。使用できるスクリプト変数は次のとおりです。
- executionContext
- トークン (token)
- node
- task
- taskInstance
スクリプトへの変数の読み込みと保存のデフォルトの動作をカスタマイズするには、variable 要素をスクリプトのサブ要素として使用します。その場合は、スクリプト式もサブ要素 expression としてスクリプトに配置します。
スクリプトが起動する前に、プロセス変数
YYY および ZZZ が、それぞれスクリプト変数 b および c としてスクリプトで使用できるようになります。スクリプトが完了すると、スクリプト変数 a の値が、プロセス変数 XXX に格納されます。
変数の access 属性に
read が含まれている場合、プロセス変数は、スクリプトが評価される前にスクリプト変数としてロードされます。access 属性に write が含まれている場合、スクリプト変数は評価後にプロセス変数として保存されます。mapped-name 属性を使用すると、スクリプト内でプロセス変数を別の名前で使用できます。これは、プロセス変数名にスペースやその他の無効な文字が含まれている場合に使用します。
6.5.5. カスタムイベント リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
GraphElement.fireEvent(String eventType, ExecutionContext executionContext); メソッドを呼び出すことで、プロセスの実行中に自由にカスタムイベントを実行できます。イベントタイプの名前は自由に選択してください。
6.6. スーパーステート リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
スーパーステートはノードのグループです。これらは再帰的にネストでき、プロセス定義に階層を追加するために使用されます。たとえば、この機能は、プロセスに属するノードをフェーズごとにグループ化するのに役立ちます。
アクションは、スーパーステートイベントに関連付けることができます。ネストされたノードのトークンによって発生したイベントは、プロセス定義までスーパーステート階層をバブルアップします。したがって、トークンは階層内のすべてのノードに同時に存在するものとして機能します。これは、たとえば、プロセス実行が起動フェーズにあるかどうかを確認する場合に便利です。
6.6.1. スーパーステート遷移 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
スーパーステートから退出する遷移は、そのスーパーステート内の任意のノードに配置されたトークンによって取得できます。この機能は、随時取得できる キャンセル 遷移のモデル化などに使用できます。
遷移はスーパーステートにも到達することがあります。その場合、トークンはドキュメント順の最初のノードにリダイレクトされます。さらに、スーパーステートの外側にあるノードは、スーパーステートの内側にあるノードに直接遷移することができ、逆もまた同様です。最後に、他のノードと同様に、スーパーステートも自己遷移できます。
6.6.2. スーパーステートイベント リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
スーパーステートには、
superstate-enter および superstate-leave という固有のイベントが 2 つあります。これらのイベントは、ノードがどの遷移に進入したか、またはどの遷移から退出したかに関係なく、発生します。スーパーステート内でトークンが遷移を取得する限り、これらのイベントは発生しません。
注記
ステートとスーパーステートには別々のイベントタイプがあります。このソフトウェアは、実際のスーパーステートイベントとスーパーステート内から渡されたノードイベントを簡単に区別できるように設計されています。
6.6.3. 階層名 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
ノード名は、スコープ 内で一意である必要があります。ノードのスコープは、その ノードコレクション です。プロセス定義とスーパーステートは、どちらもノードコレクションです。スーパーステートのノードを参照するには、スラッシュ (
/) 区切りの相対名で指定します。ノード名はスラッシュで区切られます。.. を使用して、上位レベルを参照します。次の例は、スーパーステートのノードを参照する方法を示しています。
次の例は、スーパーステート階層を上に移動する方法を示しています。
6.7. 例外処理 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
Business Process Manager の例外処理メカニズムは、Java 例外に対してのみ機能します。グラフ実行自体が問題を引き起こすことはありません。例外が発生する可能性があるのは、委譲クラス が実行されたときだけです。
exception-handler のリストは、process-definition、node、transition で指定できます。これらの各例外ハンドラーには、アクションのリストがあります。委譲クラスで例外が発生すると、プロセス要素の親階層で適切な exception-handler が検索され、そのアクションが実行されます。
重要
Business Process Manager の例外処理は、Java の例外処理といくつかの点で異なります。Java では、キャッチされた例外が 制御フロー に影響を与える可能性があります。jBPM の場合、例外処理メカニズムが制御フローを変更することはできません。例外は、キャッチされるか、キャッチされないかのいずれかです。キャッチされていない例外は、
token.signal() メソッドを呼び出したクライアントに出力されます。キャッチされた例外がある場合は、何も発生しなかったかのようにグラフ実行が続行されます。
注記
例外処理
アクション のグラフ内にある任意のノードにトークンを配置するには、Token.setNode(Node node) を使用します。
6.8. プロセス構成 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
Business Process Manager は、
process-state によって プロセス構成 をサポートしています。この状態は、別のプロセス定義に関連付けられている状態です。グラフ実行が process-state に到達すると、サブプロセスの新しいインスタンスが作成されます。このサブプロセスは、プロセス状態に到達した実行パスに関連付けられます。スーパープロセスの実行パスは、サブプロセスが終了するまで待機し、その後プロセス状態から退出し、スーパープロセスでグラフ実行を継続します。
上記の例では、
hire プロセスには、interview プロセスを生成する process-state が含まれています。first interview に実行が到達すると、interview プロセスの新しい実行 (つまり、プロセスインスタンス) が作成されます。バージョンが明示的に指定されていない場合、サブプロセスの最新バージョンが使用されます。Business Process Manager で特定のバージョンをインスタンス化するには、オプションの version 属性を指定します。サブプロセスが実際に作成されるまで、指定したバージョンまたは最新バージョンのバインドを延期するには、オプションの binding 属性を late に設定します。
次に、
hire プロセス変数 a を interview プロセス変数 aa にコピーします。同様に、hire 変数 b を インタビュー変数 bb にコピーします。面接プロセスが完了すると、変数 aa のみが a 変数に再びコピーされます。
一般に、サブプロセスが開始されると、読み取りアクセス権を持つすべての変数がスーパープロセスから読み取られ、新しく作成されたサブプロセスに取り込まれます。これは、開始状態から退出するシグナルが与えられる前に行われます。サブプロセスインスタンスが完了すると、書き込みアクセス権を持つすべての変数がサブプロセスからスーパープロセスにコピーされます。変数の mapped-name 属性を使用して、サブプロセスで使用する変数名を指定します。
6.9. カスタムノードの動作 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
任意のビジネスロジックを実行できるだけでなく、グラフ実行を渡す役割を持つ
ActionHandler の特別な実装を使用して、カスタムノードを作成します。以下の例では、ERP システムから値を読み取り、(プロセス変数から) 金額を追加し、結果を ERP システムに保存します。金額の大きさに基づいて、 small amounts 遷移または large amounts 遷移を使用して終了します。
図6.3 ERP 更新用のプロセススニペットの例
注記
カスタムノード実装でトークンを作成して結合することもできます。これを行う方法については、jBPM ソースコードのフォークノードおよびジョインノードの実装を参照してください。
6.10. グラフ実行 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
Business Process Manager のグラフ実行モデルは、プロセス定義の解釈と "チェーンオブコマンド" パターンに基づいています。
プロセス定義データはデータベースに格納され、プロセス実行中に使用されます。
注記
ランタイム時に定義情報をロードしないように、Hibernate の 2 次キャッシュが使用されることに注意してください。プロセス定義は変更されないため、Hibernate はそれらをメモリーにキャッシュできます。
"チェーンオブコマンドパターン" は、グラフ内の各ノードにプロセス実行の受け渡しを担当させます。ノードがプロセス実行を渡さない場合、ノードは
待機状態 のように動作します。
プロセスインスタンスで実行を開始すると、実行は
待機状態 に進入するまで続行されます。
トークンは実行のパスを表します。トークンには、プロセスグラフ内のノードへのポインターがあります。トークンは、
待機状態 の間、データベースで永続化することができます。
このアルゴリズムは、トークンの実行を計算するために使用されます。シグナルがトークンに送信されると実行が開始され、コマンドオブチェーンパターンを介して遷移とノードに渡されます。関連するメソッドは次のとおりです。
図6.4 グラフ実行関連のメソッド
トークンがノードにあるとき、そのトークンにシグナルを送信できます。シグナルは実行開始の命令として扱われるため、トークンの現在のノードからの
退出遷移 を指定する必要があります。最初の遷移がデフォルトです。トークンにシグナルが送信されると、遷移はトークンの現在のノードを取得し、Node.leave(ExecutionContext,Transition) メソッドを呼び出します。(ExecutionContext は、その中の主要なオブジェクトがトークンであるため、トークンと考えるのが最適です。) Node.leave(ExecutionContext,Transition) メソッドは node-leave イベントを発生させ、Transition.take(ExecutionContext) を呼び出します。このメソッドは遷移イベントを実行し、遷移の宛先ノードで Node.enter(ExecutionContext) を呼び出します。さらに、このメソッドが node-enter イベントを発生させ、Node.execute(ExecutionContext) を呼び出します。
すべてのタイプのノードには独自の動作があります。これらは
execute メソッドを介して実装されます。各ノードには、Node.leave(ExecutionContext,Transition) を再度呼び出して、グラフ実行を受け渡す役割があります。つまり、以下のようになります。
Token.signal(Transition)Node.leave(ExecutionContext,Transition)Transition.take(ExecutionContext)Node.enter(ExecutionContext)Node.execute(ExecutionContext)
注記
次の状態 (アクションの呼び出しを含む) は、クライアントのスレッドを介して計算されます。よくある誤解として、すべての計算をこの方法で行う必要があるというものがあります。むしろ、非同期呼び出し の場合と同様に、非同期メッセージング を (Java Message Service 経由で) 使用できます。メッセージがプロセスインスタンスの更新と同じトランザクションで送信されると、すべての同期の問題が正しく処理されます。一部のワークフローシステムは、グラフ内のすべてのノード間で非同期メッセージングを使用しますが、高スループット環境では、このアルゴリズムは、ビジネスプロセスのパフォーマンスを最大化を求めるユーザーに、はるかに多くの制御と柔軟性を提供します。
6.11. トランザクションの境界 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
「 グラフ実行 」 で説明したように、Business Process Manager はクライアントのスレッドでプロセスを実行し、その性質上、同期的です。実際には、これはつまり、プロセスが新しい
待機状態 に進入したときにのみ、token.signal() または taskInstance.end() が返されることを意味します。
注記
このセクションで説明されている jPDL 機能の詳細は、10章 非同期継続 を参照してください。
プロセスの実行をサーバー側のトランザクションに簡単にバインドできるため、ほとんどの場合、これが最も単純なアプローチです。プロセスは、1 つのトランザクションの空間内で 1 つの状態から次の状態に移動します。
処理中の計算には時間がかかる場合があるため、この動作は望ましくない場合があります。この問題に対処するために、Business Process Mangerには非同期メッセージングシステムが組み込まれています。このシステムは、その名前が示すように非同期でプロセスを続行できます。(もちろん、Java エンタープライズ環境では、組み込みのメッセージングシステムの代わりに Java Message Service ブローカーを使用するように jBPM を設定できます。)
jPDL は、すべてのノードで
async="true" 属性をサポートします。非同期ノードは、クライアントのスレッドでは実行されません。代わりに、非同期メッセージングシステムを介してメッセージが送信され、スレッドがクライアントに返されます (つまり、token.signal() または taskInstance.end() が返されます。)
Business Process Manger のクライアントコードは、トランザクションをコミットできます。プロセスの更新を含むトランザクションと同じトランザクションでメッセージを送信します。このようなトランザクションの全体的な結果として、トークンは次のノード (まだ実行されていないノード) に移動され、
org.jbpm.command.ExecuteNodeCommand メッセージが非同期メッセージングシステムから jBPM Command Executor に送信されます。これにより、キューからコマンドが読み取られ、実行されます。org.jbpm.command.ExecuteNodeCommand の場合、ノード実行時に処理が継続されます。(各コマンドは別々のトランザクションで実行されます。)
重要
非同期プロセスを続行できるように、
jBPM Command Executor が実行されていることを確認してください。これを行うには、Web アプリケーションの CommandExecutionServlet を設定します。
注記
プロセスモデル管理者は、非同期メッセージングに過度に配慮する必要はありません。覚えておくべき主なポイントは、トランザクションの境界です。デフォルトでは、Business Process Manger はクライアントトランザクションで動作し、プロセスが
待機状態 に進入するまで計算全体を実行します。(async="true" を使用して、プロセス内のトランザクションを区別します。)
以下に例を示します。
プロセス実行の開始と再開の両方に必要なクライアントコードは、通常の同期プロセスに必要なコードとまったく同じです。
この最初のトランザクションが発生すると、プロセス実行の
root token が node one を参照し、ExecuteNodeCommand メッセージがコマンドエグゼキューターに送信されます。
後続のトランザクションで、コマンドエグゼキューターはキューからメッセージを読み取り、
node one を実行します。アクションは、実行を渡すか、待機状態 に進入するかを決定できます。実行を渡すことを選択した場合、実行が node two に到達したときにトランザクションは終了します。
第7章 コンテキスト リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
この章では プロセス変数 について説明します。プロセス変数は、プロセスインスタンス関連の情報を保持するキーと値のペアです。
注記
コンテキスト をデータベースに保存できるようにするために、いくつかの小さな制限が適用されます。
7.1. プロセス変数へのアクセス リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
org.jbpm.context.exe.ContextInstance は、プロセス変数の中心的なインターフェイスとして機能します。次の方法で、プロセスインスタンスから ContextInstance を取得します。
ProcessInstance processInstance = ...; ContextInstance contextInstance = (ContextInstance) processInstance.getInstance(ContextInstance.class);
ProcessInstance processInstance = ...;
ContextInstance contextInstance =
(ContextInstance) processInstance.getInstance(ContextInstance.class);
基本的な操作は次のとおりです。
変数名は
java.lang.String です。デフォルトでは、Business Process Manager は次の値の型をサポートしています。(Hibernate で永続化できる他の型もサポートしています。)
java.lang.String | java.lang.Boolean |
java.lang.Character | java.lang.Float |
java.lang.Double | java.lang.Long |
java.lang.Byte | java.lang.Integer |
java.util.Date | byte[] |
java.io.Serializable |
注記
型指定のない null 値 も永続的に格納できます。
警告
プロセス変数に他の型が格納されている場合は、プロセスインスタンスを保存しないでください。例外エラーが発生します。
7.2. 変数の寿命 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プロセスアーカイブで変数を宣言する必要はありません。ランタイム時に、任意の Java オブジェクトを変数に格納します。変数が存在しない場合は、単純な
java.util.Map と同じ方法で作成されます。また、変数は削除することもできます。
ContextInstance.deleteVariable(String variableName); ContextInstance.deleteVariable(String variableName, Token token);
ContextInstance.deleteVariable(String variableName);
ContextInstance.deleteVariable(String variableName, Token token);
型は自動的に変更できます。これは、異なる型の値の変数を型で上書きできることを意味します。単純な列の更新よりも多くのデータベースとの通信が発生するため、型の変更の数は、常に制限することが重要です。
7.3. 可変永続性 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
変数はプロセスインスタンスの一部です。プロセスインスタンスをデータベースに保存すると、データベースがプロセスインスタンスと同期されます。(これにより、変数が作成、更新、および削除されます。) 詳細は、4章 永続性 を参照してください。
7.4. 可変スコープ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
各実行パス (トークン とも呼ばれます) には、独自のプロセス変数のセットがあります。変数は常に実行パスで要求されます。プロセスインスタンスには、これらのパスのツリーがあります。変数が要求されたときにパスが指定されていない場合、
ルートトークン がデフォルトで使用されます。
変数の検索は再帰的に行われます。検索は、特定の実行パスの親で実行されます。(これは、プログラミング言語で変数のスコープを設定する方法に似ています。)
存在しない変数が実行パスに設定されると、その変数は
ルートトークン に作成されます。(そのため、各変数にはデフォルトでプロセススコープがあります。) 変数トークンを "ローカル" にするには、次の例に従って明示的に作成します。
ContextInstance.createVariable(String name, Object value, Token token);
ContextInstance.createVariable(String name, Object value, Token token);
7.4.1. 変数のオーバーロード リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
変数のオーバーロード とは、各実行パスが同じ名前の変数の独自のコピーを持つことができることを意味します。これらのコピーはすべて別々に扱われ、異なる型を取ることができます。変数のオーバーロードは、同じ遷移で複数の同時実行パスを起動する場合に有用なことがあります。これらのパスを区別するのは、それぞれの変数のセットだけであるからです。
7.4.2. 変数のオーバーライド リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
変数のオーバーライド とは、ネストされた実行パス 内の変数が、よりグローバルな実行パス内の変数をオーバーライドすることを意味します。一般に、"ネストされた実行パス" は同時実行に関連しています。フォークとジョインの間の実行パスは、フォークに到達した (ネストされた) 実行パスの子です。たとえば、プロセスインスタンススコープ内の
contact という名前の変数を、ネストされた実行パス shipping および billing 内のこの変数でオーバーライドできます。
7.4.3. タスクインスタンス変数のスコープ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
タスクインスタンス変数については、「 タスクインスタンス変数 」 を参照してください。
7.5. 一時変数 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プロセスインスタンスがデータベースに永続化されると、通常の変数も永続化されます。しかし、変数をデータベースに格納せずに委譲クラスで使用する必要がある場合もあります。これは、一時変数 を使用して実現できます。
注記
一時変数の寿命は、
ProcessInstance Java オブジェクトの寿命と同じです。
注記
その性質上、一時変数は実行パスとは関係ありません。そのため、プロセスインスタンスオブジェクトには、それらのマップが 1 つしかありません。
一時変数には、コンテキストインスタンス内の独自のメソッドセットを介してアクセスできます。
processdefinition.xml ファイルで宣言する必要はありません。
Object ContextInstance.getTransientVariable(String name); void ContextInstance.setTransientVariable(String name, Object value);
Object ContextInstance.getTransientVariable(String name);
void ContextInstance.setTransientVariable(String name, Object value);
この章では、プロセス変数について詳しく説明しました。これで、このトピックの理解に自信を持てるはずです。
第8章 タスク管理 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
jBPM の中心的な役割は、プロセスの実行を 永続化 することです。この機能は、ユーザーのタスクとタスクリストを管理する場合に非常に便利です。jBPM を使用すると、プロセス全体を記述するソフトウェアを指定できます。このようなソフトウェアは、ヒューマンタスクの 待機状態 を持つことができます。
8.1. タスク リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
タスク はプロセス定義の一部です。タスクは、プロセスの実行中にタスクインスタンスを作成して割り当てる方法を定義します。
タスクは、
task-node および process-definition で定義します。最も一般的な方法は、task-node で 1 つ以上の タスク を定義することです。その場合、task-node はユーザーが引き受けるタスクを表します。プロセスの実行は、アクターがタスクを完了するまで待機する必要があります。アクターがタスクを完了すると、プロセスの実行が続行されます。task-node に追加のタスクが指定されている場合、デフォルトの動作では、すべてのタスクが終了するまで待機します。
タスクは、
process-definition で指定することもできます。この方法で指定したタスクは、名前を検索して見つけることができます。task-node 内からそれらを参照したり、アクション内から使用したりすることもできます。実際、名前が付けられたすべてのタスク (または task-node) は、process-definition で見つけることができます。
各タスク名は、必ず一意のものにします。また、タスクには
優先度 を設定します。これは、このタスク用に作成された各タスクインスタンスの初期優先度として使用されます。(この初期優先度は、後でタスクインスタンスによって変更できます。)
8.2. タスクインスタンス リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
タスクインスタンスは、
actorId (java.lang.String) に割り当てることができます。すべてのタスクインスタンスは 1 つのテーブル (JBPM_TASKINSTANCE) に格納されます。 特定のユーザーのタスクリストを取得するには、このテーブルを照会し、特定の actorId のすべてのタスクインスタンスを取得します。
jBPM のタスクリストメカニズムを使用すると、jBPM のタスクを他のタスクと組み合わせることができます。それらの他のタスクがプロセスの実行に関連していない場合でも、これは可能です。このようにして、一元的なリポジトリーで、jBPM-process-task を他のアプリケーションのタスクと簡単に組み合わせることができます。
8.2.1. タスクインスタンスのライフサイクル リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
タスクインスタンスのライフサイクルは単純です。インスタンスを作成すると、インスタンスを起動できます。起動後は、インスタンスを終了できます。終了すると、完了としてマークされます。
注記
柔軟性を確保するために、割り当て はライフサイクルには含まれていません。
- タスクインスタンスは通常、プロセスの実行が
task-nodeに進入したときに (TaskMgmtInstance.createTaskInstance(...)メソッドを介して) 作成されます。 - ユーザーインターフェイスコンポーネントが、データベースにタスクリストを照会します。これは、
TaskMgmtSession.findTaskInstancesByActorId(...)メソッドを使用して行われます。 - ユーザーからの入力を収集した後、UI コンポーネントが
TaskInstance.assign(String)、TaskInstance.start()、またはTaskInstance.end(...)を呼び出します。
タスクインスタンスは、次の 3 つの日付プロパティーによって状態を維持します。
createstartend
TaskInstance にあるそれぞれの "ゲッター" を介してこれらのプロパティーにアクセスします。
完了したタスクインスタンスは、終了日でマークされます。これは、後続のクエリーがタスクリストを検索するときに、完了したタスクインスタンスを取得しないようにするためです。ただし、完了したタスクは
JBPM_TASKINSTANCE テーブルに残ります。
8.2.2. タスクインスタンスとグラフ実行 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
タスクインスタンス は、アクターのタスクリスト内にある項目です。シグナリングタスクインスタンスは、完了時にトークンにシグナルを送信してプロセスの実行を続行するタスクインスタンスです。ブロッキングタスクインスタンスは、タスクインスタンスが完了する前に、関連するトークン (実行パス) が
task-node から退出することを禁止するタスクインスタンスです。デフォルトでは、タスクインスタンスはシグナリングおよび非ブロッキングになるように設定されています。
複数のタスクインスタンスが
task-node に関連付けられている場合、プロセス開発者は、タスクインスタンスの完了がプロセスの継続に影響を与える方法を指定できます。以下の値のいずれかを task-node の signal-property に与えます。
- last
- これはデフォルトです。最後のタスクインスタンスが完了すると、実行が続行されます。このノードへの進入時にタスクが作成されていない場合、実行が続行されます。
- last-wait
- 最後のタスクインスタンスが完了すると、実行が続行されます。このノードへの進入時にタスクが作成されていない場合、タスクが作成されるまで、タスクノードで実行が待機されます。
- first
- 最初のタスクインスタンスが完了すると、実行が続行されます。このノードへの進入時にタスクが作成されていない場合、実行が続行されます。
- first-wait
- 最初のタスクインスタンスが完了すると、実行が続行されます。このノードへの進入時にタスクが作成されていない場合、タスクが作成されるまで、タスクノードで実行が待機されます。
- unsynchronized
- この場合、タスクが作成されているか未完了であるかに関係なく、実行は常に続行されます。
- never
- この場合、タスクが作成されているか未完了であるかに関係なく、実行は続行されません。
タスクインスタンスの作成は、ランタイム時の計算に基づいて行うことができます。このような場合、
ActionHandler を task-node の node-enter イベントに追加し、create-tasks="false" を設定します。以下に例を示します。
ここで、作成するタスクは
task-node で指定します。また、process-definition で指定して、TaskMgmtDefinition から取得することもできます。(TaskMgmtDefinition は、タスク管理情報を追加してプロセス定義を拡張します。)
TaskInstance.end() メソッドは、タスクインスタンスを完了としてマークするために使用します。必要に応じて、end メソッドで遷移を指定できます。このタスクインスタンスの完了によって実行の継続がトリガーされた場合、指定された遷移を介して task-node から退出します。
8.3. 割り当て リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プロセス定義にはタスクノードが含まれます。
task-node には、0 個以上のタスクが含まれます。タスクは、プロセス定義の一部を静的に記述したものです。ランタイム時にタスクを実行すると、タスクインスタンスが作成されます。タスクインスタンスは、個人のタスクリストの 1 つのエントリーに対応します。
jBPM を使用すると、タスク割り当てのプッシュモデル (個人タスクリスト) とプルモデル (グループタスクリスト) を組み合わせて適用できます。プロセスは、タスクの責任者を決定し、責任者のタスクリストにプッシュします。タスクをアクターのプールに割り当てることもできます。この場合、各アクターはタスクをプルして、個人のタスクリストに入れます。
8.3.1. 割り当てのインターフェイス リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
AssignmentHandler インターフェイスを介してタスクインスタンスを割り当てます。
public interface AssignmentHandler extends Serializable {
void assign( Assignable assignable, ExecutionContext executionContext );
}
public interface AssignmentHandler extends Serializable {
void assign( Assignable assignable, ExecutionContext executionContext );
}
タスクインスタンスの作成時に、割り当てハンドラーの実装が呼び出されます。その時点で、タスクインスタンスは 1 つ以上のアクターに割り当てられます。
AssignmentHandler の実装は、割り当て可能なメソッド (setActorId または setPooledActors) を呼び出し、タスクを割り当てます。割り当て可能な項目は、TaskInstance または SwimlaneInstance (プロセスロール) です。
public interface Assignable {
public void setActorId(String actorId);
public void setPooledActors(String[] pooledActors);
}
public interface Assignable {
public void setActorId(String actorId);
public void setPooledActors(String[] pooledActors);
}
TaskInstance と SwimlaneInstance の両方を、特定のユーザーまたはアクターのプールに割り当てることができます。TaskInstance をユーザーに割り当てるには、Assignable.setActorId(String actorId) を呼び出します。TaskInstance を候補アクターのプールに割り当てるには、Assignable.setPooledActors(String[] actorIds) を呼び出します。
プロセス定義の各タスクをハンドラー実装に関連付けることで、ランタイム時に割り当てを実行できます。
プロセス内の複数のタスクを同じ個人またはアクターのグループに割り当てる必要がある場合は、スイムレーンの使用を検討してください (「 スイムレーン 」 を参照)。
再利用可能な
AssignmentHandler を作成するには、processdefinition.xml ファイルを使用してそれぞれを設定します。(割り当てハンドラーに設定を追加する方法の詳細は、「委譲」 を参照してください。)
8.3.2. 割り当てのデータモデル リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
タスクインスタンスとスイムレーンインスタンスのアクターへの割り当てを管理するためのデータモデルを以下に示します。各
TaskInstance には、actorId とプールされたアクターのセットがあります。
図8.1 割り当てモデルのクラス図
actorId はタスクの責任者です。プールされたアクターのセットは、候補者のコレクションを表します。候補者はタスクを引き受けると、責任者になります。actorId と pooledActors はどちらもオプションであり、組み合わせることもできます。
8.3.3. 個人タスクリスト リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
個人タスクリストは、特定の個人に割り当てられたすべてのタスクインスタンスを表します。これは、
TaskInstance の actorId プロパティーの存在によって示されます。次のいずれかの方法で、TaskInstance を個人のタスクリストに追加します。
- タスク要素の
actor-id属性に式を指定する - コード内の任意の場所から
TaskInstance.setActorId(String)メソッドを使用する AssignmentHandlerでassignable.setActorId(String)を使用する
特定のユーザーの個人タスクリストを取得するには、
TaskMgmtSession.findTaskInstances(String actorId) を使用します。
8.3.4. グループタスクリスト リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プールされたアクターは、タスクを与えられる候補者のグループです。1 人の候補者がタスクを引き受ける必要があります。多くのユーザーが同じタスクの作業を開始すると、競合が発生する可能性があるため、ユーザーはすぐにタスクの作業を開始できません。これを防ぐために、ユーザーはグループタスクリストからのみタスクインスタンスを取得して個人タスクリストに移動できます。ユーザーが作業を開始できるのは、ユーザーの個人タスクリストにタスクが追加された場合のみです。
taskInstance をユーザーのグループタスクリストに入れるには、ユーザーの actorId またはユーザーの groupId の 1 つを pooledActorIds に追加します。プールされたアクターを指定するには、次のいずれかの方法を使用します。
- プロセス内のタスク要素の属性
pooled-actor-idsに式を指定する - コード内のいずれかの場所で
TaskInstance.setPooledActorIds(String[])を使用する - AssignmentHandler で
assignable.setPooledActorIds(String[])を使用する
特定のユーザーのグループタスクリストを取得するには、ユーザーの actorId と、そのユーザーが属するすべてのグループの actorId を含むコレクションを作成します。
TaskMgmtSession.findPooledTaskInstances(String actorId) または TaskMgmtSession.findPooledTaskInstances(List actorIds) を使用して、個人タスクリストになく (actorId==null)、プールされた actorId に一致するタスクインスタンスを検索します。
注記
このソフトウェアは、アイデンティティーコンポーネントを jBPM のタスク割り当てから分離するために、このように設計されました。jBPM は、文字列のみを actorId として格納します。ユーザーとグループの関係やその他のアイデンティティー情報は認識しません。
actorId は、プールされたアクターを常にオーバーライドします。したがって、actorId と
pooledActorId のリストを持つ taskInstance は、アクターの個人タスクリストにのみ表示されます。タスクインスタンスをグループに戻すには、taskInstance の actorId プロパティを null に設定して、pooledActorId を保持します。
8.4. タスクインスタンス変数 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
タスクインスタンスは、独自の変数セットを持つことができ、プロセス変数を "認識" することもできます。タスクインスタンスは通常、実行パス (トークン) に作成されます。これにより、トークンとタスクインスタンスの間に親子関係が作成されます。これは、トークンの間の親子関係に似ています。通常のスコープ規則が適用されることに注意してください。
コントローラー を使用して、タスクインスタンススコープとプロセスのスコープ付き変数の間で変数の作成、入力、および送信を行います。
これは、タスクインスタンスが自身の変数に加えて、関連するトークンのすべての変数を '認識' できることを意味します。
コントローラーを使用すると、タスクインスタンススコープとプロセスのスコープ付き変数の間で変数の作成、入力、および送信を行うことができます。
8.5. タスクコントローラー リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
タスクインスタンスを作成したら、タスクコントローラーを使用してタスクインスタンス変数を設定できます。タスクインスタンスが終了すると、タスクコントローラーを使用して、タスクインスタンスに属するデータをプロセス変数に送信できます。
注記
タスクコントローラーの使用はオプションです。タスクインスタンスは、そのトークンに関連するプロセス変数を "認識" することもできます。タスクコントローラーは、次のタスクの実行に使用します。
- タスクインスタンス変数のコピーを作成して、プロセスが完了するまでタスクインスタンス変数への中間更新がプロセス変数に影響を与えないようにします。この時点で、コピーがプロセス変数に送信されます。
- タスクインスタンス変数は、プロセス変数と 1 対 1 の関係を持ちません。たとえば、プロセスに
sales in January、sales in January sales、およびsales in Marchという名前の変数がある場合、タスクインスタンスのフォームで、それらの 3 か月の平均売上を表示しなければならないこともあります。
タスクは、ユーザーからの入力を収集します。ただし、ユーザーにタスクを提示するために使用できるユーザーインターフェイスは多数あります。たとえば、Web アプリケーション、Swing アプリケーション、インスタントメッセンジャー、メールフォームなどがあります。そのため、タスクコントローラーは、プロセス変数 (= プロセスコンテキスト) とユーザーインターフェイスアプリケーションの間の橋渡しを行います。タスクコントローラーは、プロセス変数のビューをユーザーインターフェイスアプリケーションに提供します。
タスクインスタンスが作成されると、タスクコントローラーは、プロセス変数があればそれをタスク変数に変換します。タスク変数は、ユーザーインターフェイスフォームの入力として機能します。ユーザー入力自体はタスク変数に格納されます。ユーザーがタスクを終了すると、タスクコントローラーはタスクインスタンスデータに基づいてプロセス変数を更新します。
図8.2 タスクコントローラー
単純なシナリオでは、プロセス変数とフォームパラメーターの間に 1 対 1 のマッピングがあります。タスクコントローラーをタスク要素で指定します。このような場合、デフォルトの JBPM タスクコントローラーを使用できます。このコントローラーは、プロセス変数をタスク変数にどのようにコピーするかを表す
variable 要素のリストを取得します。
次の例は、プロセス変数に基づいて、タスクインスタンス変数の個別のコピーを作成する方法を示しています。
name 属性は、プロセス変数の名前を参照します。mapped-name はオプションで、タスクインスタンス変数の名前を参照します。mapped-name 属性を省略すると、mapped-name のデフォルトは名前に設定されます。mapped-name は、Web アプリケーションのタスクインスタンスフォームにおけるフィールドのラベルとしても使用されます。
access 属性を使用して、タスクインスタンスの作成時にコピーした変数を、タスクインスタンスの終了時にプロセス変数に書き戻すかどうかを指定します。(この情報は、適切なフォームコントロールを生成するためにユーザーインターフェイスで使用できます。) access 属性はオプションで、デフォルトのアクセスは
read,write です。
task-node は多くのタスクを持つことができますが、start-state は 1 つのタスクしか持ちません。
プロセス変数とフォームパラメーター間の単純な 1 対 1 のマッピングでは制約が大きすぎる場合は、カスタムの
TaskControllerHandler 実装を作成します。そのためのインターフェイスを以下に示します。
public interface TaskControllerHandler extends Serializable {
void initializeTaskVariables(TaskInstance taskInstance, ContextInstance contextInstance, Token token);
void submitTaskVariables(TaskInstance taskInstance, ContextInstance contextInstance, Token token);
}
public interface TaskControllerHandler extends Serializable {
void initializeTaskVariables(TaskInstance taskInstance, ContextInstance contextInstance, Token token);
void submitTaskVariables(TaskInstance taskInstance, ContextInstance contextInstance, Token token);
}
次のコードサンプルは、その設定方法を示しています。
8.6. スイムレーン リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
スイムレーン はプロセスロールです。このメカニズムを使用して、プロセス内の複数のタスクを同じアクターが引き受けるよう指定します。特定のスイムレーンの最初のタスクインスタンスが作成されると、同じスイムレーン内の後続のすべてのタスクでアクターが "記憶" されます。そのため、スイムレーンには 1 つの
割り当て があります。総裁は、「 割り当て 」 を参照してください。
特定のスイムレーンの最初のタスクが作成されると、
AssignmentHandler が呼び出されます。AssignmentHandler に渡される Assignable (割り当て可能な) 項目は、SwimlaneInstance です。特定のスイムレーンのタスクインスタンスで引き受けられた割り当ては、すべてスイムレーンインスタンスに伝播されます。タスクを引き受けるユーザーはその特定のプロセスに関する知識を持っているため、これがデフォルトの動作となっています。したがって、そのスイムレーンの後続のタスクインスタンスは、自動的にそのユーザーに割り当てられます。
8.7. 開始タスクのスイムレーン リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
スイムレーンは、開始タスクに関連付けることができます。これは、プロセスの開始者をキャプチャーするために行います。
タスクは start-state で指定できます。これにより、タスクがスイムレーンに関連付けられます。新しいタスクインスタンスが作成されると、現在の認証済みアクターが
Authentication.getAuthenticatedActorId() メソッドによりキャプチャーされます。アクターは開始タスクのスイムレーンに格納されます。
通常のメソッドを使用して、開始タスクに変数を追加します。これにより、タスクに関連付けられたフォームを定義します。詳細は、「 タスクコントローラー 」 を参照してください。
8.8. タスクイベント リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
タスクにはアクションを関連付けることができます。4 つの標準イベントタイプがあります。
task-create: タスクインスタンスが作成されたときに発生します。task-assign: タスクインスタンスが割り当てられるときに発生します。このイベントで実行されるアクションでは、executionContext.getTaskInstance().getPreviousActorId();メソッドを使用して前のアクターにアクセスできます。task-start:TaskInstance.start()メソッドが呼び出されたときに発生します。このオプション機能は、ユーザーが実際にタスクインスタンスの作業を開始していることを示すために使用します。task-end:TaskInstance.end(...)が呼び出されたときに発生します。これは、タスクの完了を示します。タスクがプロセスの実行に関連している場合、この呼び出しによってプロセスの実行が再開されることがあります。
注記
タスクには例外ハンドラーを関連付けることができます。詳細は、「 例外処理 」 を参照してください。
8.9. タスクタイマー リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
タスクにはタイマーを指定できます。「 タイマー 」 を参照してください。
タスクタイマーの cancel-event はカスタマイズできます。デフォルトでは、タスクタイマーはタスクが終了するとキャンセルされますが、タイマーの cancel-event 属性を使用すると、それを task-assign または task-start にカスタマイズできます。cancel-event は複数のイベントをサポートしています。cancel-event のタイプを組み合わせるには、属性のコンマ区切りリストでそれらを指定します。
8.10. タスクインスタンスのカスタマイズ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
タスクインスタンスをカスタマイズするには、次の手順に従います。
TaskInstanceのサブクラスを作成します。org.jbpm.taskmgmt.TaskInstanceFactory実装を作成します。- jbpm.task.instance.factory 設定プロパティーを
jbpm.cfg.xmlファイルの完全修飾クラス名に設定し、実装を設定します。 TaskInstanceのサブクラスを使用する場合は、サブクラスの Hibernate マッピングファイルを作成します (extends="org.jbpm.taskmgmt.exe.TaskInstance"を使用)。- そのマッピングファイルを
hibernate.cfg.xmlのリストに追加します。
8.11. アイデンティティーコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
ユーザー、グループ、および権限の管理は、アイデンティティー管理 と呼ばれます。jBPM には、オプションの アイデンティティーコンポーネントが含まれています。これは、自社のデータストアに簡単に置き換えることができます。
jBPM アイデンティティー管理コンポーネントは、組織モデルの情報を保持し、これを使用してタスクを割り当てます。このモデルは、ユーザー、グループ、システム、およびこれらの間の関係を記述します。オプションで、権限とロールも含めることができます。
jBPM は、このモデルを、アクターをプロセスの実際の参加者として定義することで処理します。アクターは、actorId と呼ばれる ID によって識別されます。jBPM は、actorId に関する情報のみを持ちます。actorId は、最大限の柔軟性を得るために、
java.lang.String として表されます。そのため、組織モデルとそのデータの構造に関する情報は、jBPM のコアエンジンの範囲外です。
jBPM の拡張機能として、単純なユーザーロールモデルを管理するためのコンポーネントが (将来的に) 提供される予定です。ユーザーとロール間のこのような多対多の関係は、J2EE およびサーブレット仕様で定義されているものと同じモデルであり、新規開発の出発点として役立つ可能性があります。
サーブレット、ejb、およびポートレットの仕様で使用されているユーザーロールモデルは、タスクの割り当てを処理するには不十分であることに注意してください。そのモデルは、ユーザーとロール間の多対多の関係です。これには、プロセスに関与するチームやユーザーの組織構造に関する情報は含まれません。
8.11.1. アイデンティティーモデル リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
図8.3 アイデンティティーモデルのクラス図
黄色のクラスは、後述する式の割り当てハンドラーに関連するクラスです。
User は、ユーザーまたはサービスを表します。Group は、あらゆる種類のユーザーグループです。グループをネストすることで、チーム、ビジネスユニット、および会社全体の間の関係をモデル化できます。グループには、階層グループと髪の色グループなどを区別するためのタイプがあります。Membership は、ユーザーとグループ間の多対多の関係を表します。メンバーシップは、会社内の役職を表すために使用できます。メンバーシップの名前は、ユーザーがグループ内で果たす役割を示すために使用できます。
8.11.2. 割り当て式 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
アイデンティティーコンポーネントには、タスク割り当て時にアクターを計算するための式を評価する 1 つの実装が付属しています。プロセス定義で割り当て式を使用する例を次に示します。
8.11.2.1. 最初の項 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
式は左から右に解決されます。first-term は、アイデンティティーモデルの
User または Group を指定します。後続の項は、中間のユーザーまたはグループからの次の項を計算します。
previous は、タスクが現在の認証済みアクターに割り当てられていることを意味します。これは、プロセスの前のステップを実行したアクターを意味します。
swimlane(swimlane-name) は、指定されたスイムレーンインスタンスからユーザーまたはグループを取得することを意味します。
variable(variable-name) は、指定された変数インスタンスからユーザーまたはグループを取得することを意味します。変数インスタンスには java.lang.String を含めることができます。その場合、そのユーザーまたはグループは、アイデンティティーコンポーネントから取得されます。または、変数インスタンスに User または Group オブジェクトが含まれています。
user(user-name) は、アイデンティティーコンポーネントから特定のユーザーを取得することを意味します。
group(group-name) は、アイデンティティーコンポーネントから特定のグループを取得することを意味します。
8.11.2.2. 次の項 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
group(group-type) は、ユーザーのグループを取得します。これは、前の項の結果が User である必要があることを意味します。この項は、ユーザーのすべてのメンバーシップで、指定された group-type のグループを検索します。
member(role-name) は、グループの特定のロールを実行するユーザーを取得します。前の項の結果が Group である必要があります。この項は、メンバーシップの名前が特定の role-name と一致するグループのメンバーシップを持つユーザーを検索します。
8.11.3. アイデンティティーコンポーネントの削除 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
会社のユーザーデータベースや LDAP システムなどの組織情報に独自のデータソースを使用する場合は、jBPM アイデンティティーコンポーネントを削除できます。必要な唯一のことは、
hibernate.cfg.xml から次の行を削除することです。
<mapping resource="org/jbpm/identity/User.hbm.xml"/> <mapping resource="org/jbpm/identity/Group.hbm.xml"/> <mapping resource="org/jbpm/identity/Membership.hbm.xml"/>
<mapping resource="org/jbpm/identity/User.hbm.xml"/>
<mapping resource="org/jbpm/identity/Group.hbm.xml"/>
<mapping resource="org/jbpm/identity/Membership.hbm.xml"/>
ExpressionAssignmentHandler は、アイデンティティーコンポーネントに依存しているため、そのまま使用することはできません。ExpressionAssignmentHandler を再利用してユーザーデータストアにバインドする場合は、ExpressionAssignmentHandler から拡張し、getExpressionSession メソッドをオーバーライドできます。
protected ExpressionSession getExpressionSession(AssignmentContext assignmentContext);
protected ExpressionSession getExpressionSession(AssignmentContext assignmentContext);
第9章 スケジューラー リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
この章では、Business Process Manager における タイマー の役割について説明します。
タイマーは、プロセス内のイベントで作成できます。アクションの実行またはイベントの遷移をトリガーするようにタイマーを設定します。
9.1. タイマー リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
タイマーを設定する最も簡単な方法は、timer 要素 をノードに追加することです。次のサンプルコードは、その方法を示しています。
ノードで指定されたタイマーは、そのノードが終了した後は実行されません。遷移とアクションはどちらもオプションです。タイマーが実行されると、以下のイベントが順番に発生します。
- タイプが
timerのイベントが発生します。 - アクションが指定されている場合、それが実行されます。
- シグナルにより、指定された遷移で実行が再開されます。
すべてのタイマーには一意の名前が必要です。
timer 要素に名前が指定されていない場合、デフォルトでノードの名前が使用されます。
アクション要素 (
action や script など) をサポートするには、タイマーアクションを使用します。
タイマーは、アクションによって作成およびキャンセルされます。関連する 2 つの
action-element は、create-timer と cancel-timer です。実際には、上記の timer 要素は、node-enter での create-timer アクションと node-leave での cancel-timer アクションの簡略表記です。
9.2. スケジューラーのデプロイメント リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プロセスの実行により、タイマーが作成およびキャンセルされ、タイマーストア に保存されます。別の
タイマーランナー がこのストアを確認し、各タイマーを適切なタイミングで実行します。
図9.1 スケジューラーコンポーネントの概要
第10章 非同期継続 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
10.1. 概念 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
jBPM は グラフ指向プログラミング (GOP) をベースとしています。基本的に、GOP では、同時実行パスを処理できる単純状態マシンを指定しますが、特定の実行アルゴリズムでは、すべての状態遷移が単一スレッドのクライアント操作で行われます。デフォルトでは、クライアントのスレッドで状態遷移を実行するのが適切なアプローチです。このアプローチは、サーバー側のトランザクションに自然に適合するためです。プロセスの実行は、1 つのトランザクションの空間内で、ある "待機" 状態から別の "待機" 状態に移行します。
状況によっては、開発者はプロセス定義でトランザクションの境界を微調整する必要があります。jPDL では、プロセスの実行を非同期的に継続することを
async="true" 属性で指定できます。async="true" は、イベントでトリガーされた場合にのみサポートされますが、すべてのノードタイプとすべてのアクションタイプで指定できます。
10.2. 例 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
通常、ノードは、トークンがノードに進入した後に常に実行されます。したがって、ノードはクライアントのスレッドで実行されます。2 つの例を見て、非同期継続について説明します。最初の例は、3 つのノードを持つプロセスの一部です。ノード 'a' は待機状態、ノード 'b' は自動化されたステップ、ノード 'c' は待機状態です。このプロセスには非同期の動作は含まれません。以下にその図を示します。
最初のフレームは、開始状況を示しています。トークンはノード 'a' を指しています。これは、実行パスが外部のトリガーを待機していることを意味します。そのトリガーは、トークンにシグナルを送信することによって与える必要があります。シグナルが到達すると、トークンはノード 'a' からノード 'b' への遷移を介して渡されます。トークンがノード 'b' に到達すると、ノード 'b' が実行されます。ノード 'b' は、待機状態として動作しない自動化されたステップ (メールの送信など) であることに注意してください。そのため、2 番目のフレームは、ノード 'b' が実行されているときに取得したスナップショットです。ノード 'b' はプロセスの自動化されたステップであるため、ノード 'b' の実行には、ノード 'c' への遷移を介したトークンの伝播が含まれます。ノード 'c' は待機状態です。そのため、3 番目のフレームはシグナルメソッドが返された後の最終的な状況を示しています。
図10.1 例 1: 非同期継続のないプロセス
jBPM では "永続性" は必須ではありませんが、通常、シグナルはトランザクション内で呼び出されます。そのようなトランザクションの更新を見てみましょう。まず、トークンはノード 'c' を指すように更新されます。この更新は、JDBC 接続での
GraphSession.saveProcessInstance の結果として、Hibernate によって生成されます。次に、自動化されたアクションが何らかのトランザクションリソースにアクセスして更新する場合、そのような更新は結合するか、同じトランザクションの一部にする必要があります。
2 番目の例は最初の例のバリアントであり、ノード 'b' に非同期継続が導入されています。ノード 'a' と 'c' は、最初の例と同じように動作します。つまり、待機状態として動作します。jPDL では、ノードは
async="true" 属性を設定することによって非同期としてマークされます。
async="true" をノード 'b' に追加すると、プロセスの実行が 2 つの部分に分割されます。1 つ目の部分は、ノード 'b' が実行されるポイントまでプロセスを実行します。2 つ目の部分は、ノード 'b' を実行します。 その実行は待機状態 'c' で停止します。
したがって、トランザクションは、2 つの個別のトランザクション (各部分に 1 つずつ) に分割されます。1 つ目のトランザクションでノード 'a' から退出するには、外部のトリガー (
Token.signal メソッドの呼び出し) が必要ですが、2 つ目のトランザクションは jBPM が自動的にトリガーして実行します。
図10.2 非同期継続を伴うプロセス
アクションについても、原則は同様です。
async="true" 属性でマークされたアクションは、プロセスを実行するスレッドの外部で実行されます。永続性が設定されている場合 (デフォルトの設定)、アクションは別のトランザクションで実行されます。
jBPM では、非同期メッセージングシステムを使用して非同期継続を実現します。プロセスの実行が非同期で実行されるべきポイントに到達すると、jBPM は実行を中断し、コマンドメッセージを生成してコマンドエグゼキューターに送信します。コマンドエグゼキューターは、メッセージを受信すると、停止されたプロセスの実行を再開する別のコンポーネントです。
jBPM は、JMS プロバイダーまたはそのビルトインの非同期メッセージングシステムを使用するように設定できます。ビルトインのメッセージングシステムは、機能面でかなり制限されていますが、JMS を使用できない環境でもこの機能をサポートできます。
10.3. ジョブエグゼキューター リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
ジョブエグゼキューター は、プロセスの実行を非同期的に再開するコンポーネントです。ジョブメッセージが非同期メッセージングシステムを介して到達するのを待機し、それらを実行します。非同期継続に使用される 2 つのジョブメッセージは、
ExecuteNodeJob と ExecuteActionJob です。
これらのジョブメッセージは、プロセスの実行によって生成されます。プロセスの実行中、非同期で実行する必要があるノードまたはアクションごとに、
Job (Plain Old Java Object) が MessageService に送信されます。メッセージサービスは、JbpmContext に関連付けられており、送信する必要があるすべてのメッセージを収集します。
メッセージは
JbpmContext.close() の一部として送信されます。このメソッドは、close() の呼び出しを、関連するすべてのサービスに対してカスケードします。実際のサービスは jbpm.cfg.xml で設定できます。サービスの 1 つである JmsMessageService は、デフォルトで設定されており、新しいジョブメッセージが利用可能であることをジョブエグゼキューターに通知します。
グラフ実行メカニズムは、インターフェイス
MessageServiceFactory および MessageService を使用してメッセージを送信します。これは、非同期メッセージングサービスを設定可能にするためです (これも jbpm.cfg.xml にあります)。Java EE 環境では、DbMessageService を JmsMessageService に置き換えて、アプリケーションサーバーの機能を活用できます。
以下は、ジョブエグゼキューターの仕組みの簡単な要約です。
"ジョブ" はデータベース内のレコードです。また、ジョブはオブジェクトであり、実行可能なものです。タイマーと非同期メッセージはどちらもジョブです。非同期メッセージの場合、dueDate は、メッセージが挿入されたときに現在の時刻に設定されます。ジョブエグゼキューターは、ジョブを実行する必要があります。これは 2 つのフェーズで行われます。
- ディスパッチャースレッドはジョブを取得する必要があります。
- エグゼキュータースレッドはジョブを実行する必要があります。
ジョブの取得とジョブの実行は、2 つの別個のトランザクションで行われます。ディスパッチャースレッドは、このノード上のすべてのエグゼキュータースレッドに代わって、データベースからジョブを取得します。エグゼキュータースレッドは、ジョブを受け取ると、その名前をジョブの所有者フィールドに追加します。各スレッドには、IP アドレスとシーケンス番号に基づく一意の名前があります。
ジョブの取得と実行の間に、スレッドが失敗することがあります。このような状況が発生した後にクリーンアップを行うために、ロック時間を確認するロックモニタースレッドがジョブエグゼキューターごとに 1 つあります。ロックモニタースレッドは、10 分以上ロックされていたジョブのロックを解除し、別のジョブ実行スレッドで実行できるようにします。
Hibernate の楽観的ロックを正しく機能させるためには、分離レベルを
REPEATABLE_READ に設定する必要があります。REPEATABLE_READ に設定すると、競合するトランザクションのうちの 1 つに含まれる 1 つの行だけが、このクエリーによって確実に更新されます。
update JBPM_JOB job
set job.version = 2
job.lockOwner = '192.168.1.3:2'
where
job.version = 1
update JBPM_JOB job
set job.version = 2
job.lockOwner = '192.168.1.3:2'
where
job.version = 1
繰り返し不可能な読み取りに設定すると、異常が発生する可能性があります。トランザクションは、以前に読み取ったデータを再び読み取り、トランザクションの前回の読み取り以降にコミットされた別のトランザクションによってデータが変更されていることを検出します。
繰り返し不可能な読み取りは楽観的ロックの問題です。そのため、分離レベル
READ_COMMITTED では、繰り返し不可能な読み取りが発生する可能性があるため、十分ではありません。そのため、複数のジョブ実行スレッドを設定する場合は、REPEATABLE_READ が必要です。
ジョブエグゼキューターに関連する設定プロパティーは次のとおりです。
- jbpmConfiguration
- 設定の取得元の Bean。
- name
- このエグゼキューターの名前。重要1 台のマシンで複数の jBPM インスタンスが起動している場合、この名前はノードごとに一意である必要があります。
- nbrOfThreads
- 起動しているエグゼキュータースレッドの数。
- idleInterval
- 保留中のジョブがない場合に、ジョブキューを確認するまでにディスパッチャースレッドが待機する間隔。注記ジョブがキューに追加されると、ディスパッチャースレッドに自動的に通知されます。
- retryInterval
- 実行中にジョブが失敗した場合に、ジョブが次の再試行まで待機する間隔。このデフォルト値は 3 回です。注記再試行の最大回数は、jbpm.job.retries で設定されます。
- maxIdleInterval
- idleInterval の最長期間。
- historyMaxSize
- このプロパティーは非推奨であり、効果はありません。
- maxLockTime
- ロックモニタースレッドがロックを解除する前にジョブをロックできる最大時間。
- lockMonitorInterval
- ロックされたジョブの確認の間にロックモニタースレッドがスリープする期間。
- lockBufferTime
- このプロパティーは非推奨であり、効果はありません。
10.4. jBPM のビルトインの非同期メッセージング リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
jBPM のビルトインの非同期メッセージングを使用する場合、ジョブメッセージはデータベースに永続化されて送信されます。このメッセージの永続化は、jBPM プロセスの更新と同じトランザクションまたは JDBC 接続で行うことができます。
ジョブメッセージは
JBPM_JOB テーブルに格納されます。
POJO コマンドエグゼキューター (
org.jbpm.msg.command.CommandExecutor) は、データベーステーブルからメッセージを読み取り、実行します。POJO コマンドエグゼキューターの典型的なトランザクションは次のようになります。
- 次のコマンドメッセージの読み取り
- コマンドメッセージの実行
- コマンドメッセージの削除
コマンドメッセージの実行が失敗した場合、トランザクションはロールバックされます。その後、データベース内のメッセージにエラーメッセージを追加する新しいトランザクションが開始されます。コマンドエグゼキューターは、例外を含むメッセージをすべて除外します。
図10.3 POJO コマンドエグゼキューターのトランザクション
コマンドメッセージに例外を追加するトランザクションが失敗すると、ロールバックされます。メッセージは例外のない状態でキューに残り、後で再試行されます。
重要
jBPM のビルトインの非同期メッセージングシステムは、マルチノードロックをサポートしていません。POJO コマンドエグゼキューターを複数回デプロイして、同じデータベースを使用するように設定することはできません。
第11章 ビジネスカレンダー リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
この章では、タスクとタイマーの期日を計算するために使用する Business Process Manager のカレンダー機能について説明します。
これは、基準日に期間を加算または減算することによって行われます。(基準日を省略した場合、デフォルトで現在の日付が使用されます。)
11.1. 期日 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
期日は、期間と基準日で構成されます。使用する式は次のとおりです。
duedate ::= [<basedate> +/-] <duration>
11.1.1. 期間 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
期間は、次の式を使用して、絶対時間または営業時間で指定されます。
duration ::= <quantity> [business] <unit>
上記の計算の
<quantity> は、Double.parseDouble (quantity) で解析可能なテキストである必要があります。<unit> は、秒、分、時、日、週、月、年のいずれかになります。オプションの business フラグを追加すると、当該の期間で営業時間のみが考慮されます。(これがない場合、期間は絶対時間として解釈されます。)
11.1.2. 基準日 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
基準日は次のように計算されます。
basedate ::= <EL>
上記の式の
<EL> は、Java Date または Calendar オブジェクトに解決される任意の Java Expression Language 式にすることができます。
警告
他のオブジェクトタイプの変数を参照しないでください。
JbpmException エラーが発生します。
基準日は、単純なタイマーの duedate 属性、タスクリマインダー、タスク内のタイマーなど、多くの場所でサポートされています。しかし、これらの要素の repeat 属性ではサポートされていません。
11.1.3. 期日の例 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
次の使用法はすべて有効です。
11.2. カレンダーの設定 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
org/jbpm/calendar/jbpm.business.calendar.properties ファイルで営業時間を定義します。(この設定ファイルをカスタマイズするには、変更したコピーをクラスパスのルートに配置します。)
以下は、
jbpm.business.calendar.properties にあるデフォルトの営業時間の仕様です。
11.3. 例 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
次の例は、カレンダーのさまざまな使用方法を示しています。
この章では、ビジネスカレンダーの仕組みを説明しました。
第12章 メールサポート リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
この章では、JPDL で利用できる "標準" のメールサポートについて説明します。メール機能のさまざまな要素を設定する方法は、以下の情報を参照してください。
12.1. JPDL におけるメール リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プロセスからメールを送信する時点を指定する方法は、4 つあります。
12.1.1. メールアクション リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プロセスグラフ内のノードとしてメールを表示しない理由がある場合は、メールアクション を使用します。
注記
メールアクションは、通常のアクションを追加できる場所なら、どこでもプロセスに追加できます。
<mail actors="#{president}" subject="readmylips" text="nomoretaxes" />
<mail actors="#{president}" subject="readmylips" text="nomoretaxes" />
次のように、件名とテキストの属性を要素として指定します。
<mail actors="#{president}" >
<subject>readmylips</subject>
<text>nomoretaxes</text>
</mail>
<mail actors="#{president}" >
<subject>readmylips</subject>
<text>nomoretaxes</text>
</mail>
各フィールドには、JSF ライクな式を含めることができます。
<mail
to='#{initiator}'
subject='websale'
text='your websale of #{quantity} #{item} was approved' />
<mail
to='#{initiator}'
subject='websale'
text='your websale of #{quantity} #{item} was approved' />
注記
式の詳細は、「 式 」 を参照してください。
受信者は、actors と to という 2 つの属性で指定します。to 属性は、メールアドレスのセミコロン区切りリストに "解決" される必要があります。actors 属性は、actorIds のセミコロン区切りリストに解決される必要があります。これらの actorIds は、さらにメールアドレスに解決されます。詳細は、「 アドレス解決 」 を参照してください。
<mail
to='admin@mycompany.com'
subject='urgent'
text='the mailserver is down :-)' />
<mail
to='admin@mycompany.com'
subject='urgent'
text='the mailserver is down :-)' />
注記
受信者を指定する方法は、「 メールの受信者の指定 」 を参照してください。
メールは、テンプレートを使用して定義できます。テンプレートプロパティーを次のように上書きします。
<mail template='sillystatement' actors="#{president}" />
<mail template='sillystatement' actors="#{president}" />
注記
テンプレートの詳細は、「 メールテンプレート 」 を参照してください。
12.1.2. メールノード リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
メールアクションと同様に、メールを送信するアクションも、ノードとしてモデル化できます。この場合、ランタイムの動作は同じですが、メールは プロセスグラフ 内のノードとして表示されます。
メールノードは、
メールアクション とまったく同じ属性と要素をサポートします。(詳細は、「 メールアクション 」 を参照してください。)
重要
メールノードにある 退出 遷移が 1 つだけであることを必ず確認してください。
12.1.3. "タスク割り当て" メール リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
タスクがアクターに割り当てられたときに、通知メールを送信できます。この機能を設定するには、次の方法でタスクに
notify="yes" 属性を追加します。
<task-node name='a'>
<task name='laundry' swimlane="grandma" notify='yes' />
<transition to='b' />
</task-node>
<task-node name='a'>
<task name='laundry' swimlane="grandma" notify='yes' />
<transition to='b' />
</task-node>
notify を
yes、true、または on に設定すると、Business Process Manager は、タスクに割り当てられているアクターにメールを送信します。(このメールはテンプレートに基づいており、Web アプリケーションのタスクページへのリンクが含まれています。)
12.1.4. "タスクリマインダー" メール リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
タスクのリマインダーとしてメールを送信できます。JPDL の reminder 要素はタイマーを利用します。最も一般的に使用される属性は、duedate と repeat です。アクションを指定する必要はありません。
12.2. メールにおける式 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
式では、変数 swimlanes、process variables、および transient variables beans を使用できます。これらは、
jbpm.cfg.xml ファイルで設定します。
式は、アドレス解決 機能と組み合わせることができます。詳細は、「 アドレス解決 」 を参照してください。
この例では、
president という名前の swimlane が存在することを前提としています。
<mail actors="#{president}"
subject="readmylips"
text="nomoretaxes" />
<mail actors="#{president}"
subject="readmylips"
text="nomoretaxes" />
このコードは、その特定のプロセスの実行において
president として振る舞うユーザーにメールを送信します。
12.3. メールの受信者の指定 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
12.3.1. 複数の受信者 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
複数の受信者を、actors および to フィールドにリストできます。リスト内の項目は、コロンまたはセミコロンで区切ります。
12.3.2. BCC アドレスへのメールの送信 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
ブラインドカーボンコピー (BCC) 受信者にメッセージを送信するには、プロセス定義の bccActors 属性と bcc 属性のいずれかを使用します。
<mail to='#{initiator}'
bcc='bcc@mycompany.com'
subject='websale'
text='your websale of #{quantity} #{item} was approved' />
<mail to='#{initiator}'
bcc='bcc@mycompany.com'
subject='websale'
text='your websale of #{quantity} #{item} was approved' />
別の方法として、
jbpm.cfg.xml で一元的に設定されている場所に BCC メッセージを常に送信する方法があります。次の例は、その方法を示しています。
<jbpm-configuration>
...
<string name="jbpm.mail.bcc.address" value="bcc@mycompany.com" />
</jbpm-configuration>
<jbpm-configuration>
...
<string name="jbpm.mail.bcc.address" value="bcc@mycompany.com" />
</jbpm-configuration>
12.3.3. アドレス解決 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
Business Process Manger 全体で、アクターは
actorIds によって参照されます。これは、プロセスの参加者を識別するための文字列です。アドレスリゾルバー は、actorIds をメールアドレスに変換します。
アドレス解決を適用するには、actors 属性を使用します。これに対して、アドレスを直接追加する場合は、アドレス解決の適用を実行しない to 属性を使用します。
アドレスリゾルバーが次のインターフェイスを実装していることを確認してください。
public interface AddressResolver extends Serializable {
Object resolveAddress(String actorId);
}
public interface AddressResolver extends Serializable {
Object resolveAddress(String actorId);
}
アドレスリゾルバーは、文字列、文字列のコレクション、または文字列の配列の 3 つの型のいずれかを返します。(文字列は、必ず特定の
actorId のメールアドレスを表すものである必要があります。)
アドレスリゾルバーの実装が Bean であることを確認してください。この Bean は、次の例のように、
jbpm.mail.address.resolver という名前の jbpm.cfg.xml ファイルで設定する必要があります。
<jbpm-configuration>
<bean name='jbpm.mail.address.resolver'
class='org.jbpm.identity.mail.IdentityAddressResolver'
singleton='true' />
</jbpm-configuration>
<jbpm-configuration>
<bean name='jbpm.mail.address.resolver'
class='org.jbpm.identity.mail.IdentityAddressResolver'
singleton='true' />
</jbpm-configuration>
Business Process Manger の
アイデンティティー コンポーネントには、アドレスリゾルバーが含まれています。このアドレスリゾルバーは、特定の actorId のユーザーを探します。ユーザーが存在する場合、そのメールアドレスが返されます。そうでない場合は、null が返されます。
注記
アイデンティティーコンポーネントの詳細は、「 アイデンティティーコンポーネント 」 を参照してください。
12.4. メールテンプレート リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
processdefinition.xml ファイルを使用してメールを指定する代わりに、テンプレートを使用できます。この場合も、各フィールドを processdefinition.xml で上書きできます。次のようにテンプレートを指定します。
メールテンプレートでは、追加の変数を定義できます。この変数は式で使用できます。
次のように、
jbpm.cfg.xml でテンプレートを含むリソースを設定します。
<jbpm-configuration> <string name="resource.mail.templates" value="jbpm.mail.templates.xml" /> </jbpm-configuration>
<jbpm-configuration>
<string name="resource.mail.templates" value="jbpm.mail.templates.xml" />
</jbpm-configuration>
12.5. メールサーバーの設定 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
次のコード例に従って、
jbpm.cfg.xml ファイルの jbpm.mail.smtp.host プロパティーを設定して、メールサーバーを設定します。
<jbpm-configuration>
<string name="jbpm.mail.smtp.host" value="localhost" />
</jbpm-configuration>
<jbpm-configuration>
<string name="jbpm.mail.smtp.host" value="localhost" />
</jbpm-configuration>
または、さらにプロパティーを指定する必要がある場合は、次の方法でプロパティーファイルへのリソース参照を指定します。
<jbpm-configuration> <string name='resource.mail.properties' value='jbpm.mail.properties' /> </jbpm-configuration>
<jbpm-configuration>
<string name='resource.mail.properties' value='jbpm.mail.properties' />
</jbpm-configuration>
12.6. メール認証 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
12.6.1. メール認証の設定 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
次の設定を使用して、メールを送信するときに (SMTP) 認証を有効にすることができます。
| プロパティー | タイプ | 説明 |
|---|---|---|
| jbpm.mail.user |
string
|
ユーザーのメールアドレス
|
| jbpm.mail.password |
string
|
そのメールアドレスのパスワード
|
| jbpm.mail.smtp.starttls |
boolean
|
SMTP サーバーで STARTTLS プロトコルを使用するかどうか
|
| jbpm.mail.smtp.auth |
boolean
|
SMTP 認証プロトコルを使用するかどうか
|
| jbpm.mail.debug |
boolean
|
javax.mail.Session インスタンスをデバッグモードに設定するかどうか
|
12.6.2. メール認証のロジック リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
上記のプロパティーに関しては、次のロジックが適用されます。
jbpm.mail.user プロパティーも jbpm.mail.password プロパティーも設定されていない場合、他の設定に関係なく認証は使用されません。
jbpm.mail.user プロパティーが設定されている場合、次の処理が行われます。
- mail.smtp.submitter プロパティーが jbpm.mail.user プロパティーの値で設定されます。
- jbpm エンジンが、メールの送信時に smtp サーバーへのログインを試みます。
jbpm.mail.user プロパティーと jbpm.mail.password プロパティーが設定されている場合、次の処理が行われます。
- この場合にも、少なくとも jbpm.mail.user を設定した場合の処理が行われます。
- jbpm.mail.smtp.auth プロパティーの値に関係なく、mail.smtp.auth プロパティーは true に設定されます。
12.7. "From" アドレスの設定 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
From アドレスフィールドのデフォルト値は、jbpm@noreply です。次のように、キー jbpm.mail.from.address を使用して jbpm.xfg.xml ファイルで設定します。
<jbpm-configuration>
<string name='jbpm.mail.from.address' value='jbpm@yourcompany.com' />
</jbpm-configuration>
<jbpm-configuration>
<string name='jbpm.mail.from.address' value='jbpm@yourcompany.com' />
</jbpm-configuration>
12.8. メールサポートのカスタマイズ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
Business Process Manager のすべてのメールサポートは、1 つのクラス、つまり
org.jbpm.mail.Mail に一元化されています。このクラスは ActionHandler の実装です。process XML でメールが指定されるたびに、mail クラスへの委譲が行われます。特定のニーズに合わせて、mail クラスから継承し、特定の動作をカスタマイズすることができます。メール委譲に使用するクラスを設定するには、次のように jbpm.cfg.xml で jbpm.mail.class.name 設定文字列を指定します。
<jbpm-configuration> <string name='jbpm.mail.class.name' value='com.your.specific.CustomMail' /> </jbpm-configuration>
<jbpm-configuration>
<string name='jbpm.mail.class.name'
value='com.your.specific.CustomMail' />
</jbpm-configuration>
カスタマイズされたメールクラスは、解析時に読み取られます。アクションは、設定済み (またはデフォルト) のメールクラス名を参照するプロセス内で設定されます。したがって、プロパティーが変更された場合、すでにデプロイされているすべてのプロセスは、引き続き古いメールクラス名を参照します。これは、jBPM データベースに対して update ステートメントを送信するだけで変更できます。
この章では、さまざまなメール設定を行う方法について詳しく説明しました。お使いの環境で設定を練習することをお勧めします。
第13章 ロギング リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
この章では、Business Process Manager のロギング機能と、その機能を利用するさまざまな方法について説明します。
ロギングの目的は、プロセス実行の履歴を記録することです。各プロセス実行のランタイムデータが変更されると、変更がログに保存されます。
注記
この章で説明する プロセスロギング は、ソフトウェアロギング と混同しないよう注意してください。ソフトウェアロギングは、ソフトウェアプログラムの実行を (通常はデバッグ目的で) トレースします。プロセスロギングは、対照的に、プロセスインスタンスの実行を追跡します。
プロセスのログ情報が役立つ場面は数多くあります。これらの中で最も明白なのは、プロセス実行参加者によるプロセス履歴の参照です。
もう 1 つのユースケースは、ビジネスアクティビティーモニタリング (BAM) のユースケースです。これを使用すると、プロセス実行のログを照会または分析し、ビジネスプロセスに関する有用な統計情報を見つけることができます。この情報は、組織で "実際" のビジネスプロセス管理を実装する際の鍵となります。(実際のビジネスプロセス管理とは、組織がそのプロセスを管理する方法、情報技術によるプロセスのサポート方法、および反復的なプロセスでこれら 2 つを使用して相互に改善する方法に関係します。)
プロセスログは、"元に戻す" 操作の実装にも使用できます。ログには、ランタイムのすべての情報変更に関するレコードが含まれているため、変更を逆の順序で "再生" することで、プロセスを前の状態に戻すことができます。
13.1. ログの作成 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
Business Process Manager モジュールは、プロセスの実行時にログを生成します。ただし、ユーザーはプロセスログを挿入することもできます。(ログエントリーは、
org.jbpm.logging.log.ProcessLog から継承する Java オブジェクトです。) プロセスログのエントリーは、ProcessInstance のオプションの拡張である LoggingInstance に追加されます。
Business Process Manager は、グラフ実行ログ、コンテキストログ、タスク管理ログなど、さまざまな種類のログを生成します。
org.jbpm.logging.log.ProcessLog から始めることをお勧めします。これを使用して、継承ツリー の下層に移動することができるためです。
LoggingInstance は、すべてのログエントリーを収集します。ProcessInstance が保存されると、ログエントリーはここからデータベースにフラッシュされます。(ProcessInstance の logs フィールドは Hibernate にマッピングされていません。これは、各トランザクションでデータベースから取得されるこれらのログを回避するためです。)
各
ProcessInstance は実行パスのコンテキストで作成されるため、ProcessLog はそのトークンを参照します。トークンは、インデックスシーケンスジェネレーター としても機能します。(これにより後続のトランザクションで生成されるログに連続したシーケンス番号が付けられるため、これはログの取得にとって重要です。)
次の API メソッドを使用して、プロセスログを追加します。
public class LoggingInstance extends ModuleInstance {
...
public void addLog(ProcessLog processLog) {...}
...
}
public class LoggingInstance extends ModuleInstance {
...
public void addLog(ProcessLog processLog) {...}
...
}
以下は、情報ログの UML 図です。
図13.1 jBPM のログ情報のクラス図
CompositeLog は特殊なケースです。これは、多数の子の親ログとして機能するため、階層構造を適用する手段を提供します。ログの挿入には、次のアプリケーションプログラミングインターフェイスを使用します。
階層構造が一貫していることを確認するために、
CompositeLog は常に try-finally-block で呼び出す必要があります。以下はその例です。
13.2. ログ設定 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
特定のデプロイメントにとってログが重要でない場合は、
jbpm.cfg.xml 設定ファイルのセクション jbpm-context からロギングの行を削除します。
<service name='logging'
factory='org.jbpm.logging.db.DbLoggingServiceFactory' />
<service name='logging'
factory='org.jbpm.logging.db.DbLoggingServiceFactory' />
ログをフィルタリングするには、
LoggingService のカスタム実装を記述します (これは DbLoggingService のサブクラスです)。その後、ロギング用のカスタム ServiceFactory を作成し、それを factory 属性で指定します。
13.3. ログの取得 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プロセスインスタンスのログは、常にデータベースクエリーを介して取得する必要があります。
LoggingSession を介してこれを実現するには、2 つの方法があります。
最初の方法は、プロセスインスタンスのすべてのログを取得する方法です。これらのログは、マップ内のトークンごとにグループ化されます。このマップは、
ProcessLog のリストをプロセスインスタンス内のすべてのトークンに関連付けます。リストには、作成された順序と同じ順序で ProcessLogs が含まれます。
public class LoggingSession {
...
public Map findLogsByProcessInstance(long processInstanceId) {...}
...
}
public class LoggingSession {
...
public Map findLogsByProcessInstance(long processInstanceId) {...}
...
}
2 番目の方法は、特定のトークンのログを取得する方法です。リストには、作成された順序と同じ順序で
ProcessLogs が含まれます。
public class LoggingSession {
public List findLogsByToken(long tokenId) {...}
...
}
public class LoggingSession {
public List findLogsByToken(long tokenId) {...}
...
}
この章では、jBPM のロギングの仕組みとロギングのさまざまな用途の概要を説明しました。
第14章 jBPM プロセス定義言語 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
jBPM プロセス定義言語 (jPDL) は、jBPM フレームワークによって認識され、XML スキーマとして表現されるビジネスプロセスを定義するための表記法です。多くの場合、プロセス定義には、jPDL ドキュメントに加えてサポートファイルが必要です。これらのファイルはすべて、デプロイメントの プロセスアーカイブ にパッケージ化されています。
14.1. プロセスアーカイブ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プロセスアーカイブは、特定の内容レイアウトを持つ単なる ZIP アーカイブです。プロセスアーカイブの中心となるファイルは、
processdefinition.xml と呼ばれます。このファイルは、ビジネスプロセスを jPDL 表記で定義し、自動化されたアクションとヒューマンタスクに関する情報を提供します。プロセスアーカイブには、アクションハンドラークラスやユーザーインターフェイスタスクフォームなど、プロセスに関連する他のファイルも含まれます。
14.1.1. プロセスアーカイブのデプロイ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プロセスアーカイブ は、次のいずれかの方法でデプロイできます。
- Process Designer Tool
- ant タスク
- プログラム
Process Designer Tool を使用してプロセスアーカイブをデプロイするには、プロセスアーカイブフォルダーを右クリックし、 オプションを選択します。
jBPM アプリケーションサーバー統合モジュールには、gpd-deployer Web アプリケーションが含まれています。このアプリケーションは、
GPD Deployer Servlet と呼ばれる、プロセスアーカイブをアップロードするためのサーブレットを備えています。このサーブレットは、プロセスアーカイブを受信し、設定されたデータベースにデプロイできます。
ant タスクを使用してプロセスアーカイブをデプロイするには、次のようにタスクを定義して呼び出します。
より多くのプロセスアーカイブを一度にデプロイするには、ネストされた fileset 要素を使用します。
DeployProcessTask の属性は次のとおりです。
| 属性 | 説明 | 必須かどうか |
|---|---|---|
| process |
プロセスアーカイブへのパス。
|
はい。ネストされたリソースコレクション要素が使用されている場合を除きます。
|
| jbpmcfg |
デプロイメント時にロードする jBPM 設定リソース。
|
いいえ。デフォルトは
jbpm.cfg.xml です。
|
| failonerror |
false の場合、プロセス定義がデプロイに失敗したときに、警告メッセージをログに記録しますが、ビルドは停止しません。
| いいえ。デフォルトは true です。 |
プロセスアーカイブをプログラムでデプロイするには、
org.jbpm.graph.def.ProcessDefinition クラスのいずれかの parseXXX メソッドを使用します。
14.1.2. プロセスのバージョン管理 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プロセスインスタンスは常に、それが起動されたプロセス定義と同じプロセス定義で実行されます。ただし、jBPM では、同じ名前の複数のプロセス定義がデータベースに共存できます。通常、プロセスインスタンスは、その時点で利用可能な最新バージョンで起動し、その存続期間全体にわたって同じプロセス定義で実行され続けます。新しいバージョンがデプロイされると、新しく作成されたインスタンスは最新バージョンで起動しますが、古いプロセスインスタンスは古いプロセス定義で実行され続けます。
プロセスに Java クラスへの参照が含まれている場合、これら Java クラスは次の 2 つの方法のいずれかで jBPM ランタイム環境で使用できるようになります。
- jBPM クラスローダーがこれらのクラスを認識できるようにするそのためには、委譲クラスを
jbpm-jpdl.jarの "隣" の.jarファイルに入れて、すべてのプロセス定義がそのクラスファイルを参照できるようにします。Java クラスもプロセスアーカイブに含めることができます。委譲クラスをプロセスアーカイブに含めた場合 (そしてそれらが jbpm クラスローダーによって認識されない場合)、jBPM はこれらのクラスをプロセス定義内でバージョン管理します。注記プロセスクラスローディングの詳細は、「委譲」 を参照してください。
プロセスアーカイブがデプロイされると、jBPM データベースに プロセス定義 が作成されます。プロセス定義は、名前に基づいてバージョン管理します。名前付きのプロセスアーカイブがデプロイされると、デプロイヤーがそれにバージョン番号を割り当てます。これは、同じ名前のプロセス定義に割り当てられている最大の番号を検索し、その値に 1 を追加することによって行われます。(名前のないプロセス定義は、常に
-1 という形でバージョン付けされます。)
14.1.3. デプロイされたプロセス定義の変更 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
警告
デプロイ後にプロセス定義を変更することは推奨できません。プロセスインスタンスを新しいバージョンのプロセス定義に移行することを推奨します。
このプロセスを行う前に、次の要因を考慮してください。
org.jbpm.db.GraphSessionのメソッドloadProcessDefinition、findProcessDefinitionを介してロードされたプロセス定義、またはアソシエーショントラバーサルを介して到達されたプロセス定義の更新に制限はありません。ただし、setStartState(null)などのいくつかの呼び出しにより、プロセスが台無しになることが 非常によくある ため、注意してください。- プロセス定義は変更されることが想定されていないため、出荷時の Hibernate 設定では、定義クラスとコレクションの
nonstrict-read-writeキャッシュストラテジーが指定されています。このストラテジーにより、コミットされていない更新を他のトランザクションから認識できるようになります。
14.1.4. プロセスインスタンスの移行 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プロセス定義を変更する別の方法は、各プロセスインスタンスを新しいバージョンに移行することです。ビジネスプロセスは長期にわたって存続するため、移行は簡単ではないことを考慮してください。
注記
これは実験的な機能です。
定義データ、実行データ、ロギングデータは明確に区別されます。この区別が存在するため、まずプロセスの新しいバージョンをまずデプロイする必要があります。その後で、プロセスインスタンスを新しいバージョンに移行します。トークンまたはタスクインスタンスが、ターゲットプロセス定義で削除されたノードまたはタスク定義を参照している場合は、移行時に変換が必要でます。ロギングデータは 2 つのプロセス定義に分散されることに注意してください。これにより、ツールを開発して統計情報の計算を行う際に問題が発生することがあります。
プロセスインスタンスを新しいバージョンに移行するには、以下に示すように
ChangeProcessInstanceVersionCommand を実行します。
new ChangeProcessInstanceVersionCommand()
.processName("commute")
.nodeNameMappingAdd("drive to destination", "ride bike to destination")
.execute(jbpmContext);
new ChangeProcessInstanceVersionCommand()
.processName("commute")
.nodeNameMappingAdd("drive to destination", "ride bike to destination")
.execute(jbpmContext);
14.2. 委譲 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
委譲 メカニズムを使用して、プロセス実行にカスタムコードを含めます。
14.2.1. jBPM クラスローダー リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
jBPM クラスローダーは、jBPM クラスをロードするローダーです。クラスを jBPM クラスローダーから認識可能にするには、クラスを JAR ファイルにパックし、JAR を
jbpm-jpdl.jar と同じ場所に配置します。Web アプリケーションの場合、カスタム JAR ファイルを jbpm-jpdl.jar と一緒に WEB-INF/lib に配置します。
14.2.2. プロセスクラスローダー リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
委譲クラスは、それぞれの プロセスクラスローダー を介してロードされます。プロセスクラスローダーは、親として jBPM クラスローダーを持ちます。これは、1 つの特定のプロセス定義でデプロイされたクラスを追加します。クラスをプロセス定義に追加するには、それらをプロセスアーカイブの
classes ディレクトリーに配置します。これは、プロセス定義に追加されたクラスをバージョン管理する場合にのみ役立つことに注意してください。バージョン管理が不要な場合は、代わりにクラスを jBPM クラスローダーで使用できるようにします。
リソース名がスラッシュで始まらない場合、リソースはプロセスアーカイブの
classes ディレクトリーからも読み込まれます。このディレクトリーの外にあるリソースをロードするには、パスの先頭に二重スラッシュ (//) を付けます。たとえば、プロセスアーカイブのルートにある data.xml をロードするには、class.getResource("//data.xml") を呼び出します。
14.2.3. 委譲の設定 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
委譲クラスには、プロセス実行内から呼び出されるユーザーコードが含まれます。最も一般的な例は アクション です。アクションの場合、プロセス内のイベントで
ActionHandler インターフェイスの実装を呼び出すことができます。委譲は、processdefinition.xml ファイルで指定します。委譲を指定するときに、次の 3 つのデータを指定できます。
- クラス名 (必須): これは委譲クラスの完全修飾名です。
- 設定タイプ (オプション): これは、委譲オブジェクトをインスタンス化して設定する方法を指定します。デフォルトでは、コンストラクターが使用され、設定情報は無視されます。
- 設定 (オプション): これは委譲オブジェクトの設定であり、設定タイプに必要な形式である必要があります。
設定の各タイプを以下に説明します。
14.2.3.1. config-type フィールド リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
これはデフォルトの設定タイプです。config-type フィールドは、まず委譲クラスのオブジェクトをインスタンス化してから、設定で指定されたオブジェクトフィールドに値を設定します。設定は XML ファイルに保存されます。このファイルでは、要素名がクラスのフィールド名に対応している必要があります。要素の内容テキストは、対応するフィールドに配置されます。必要かつ可能な場合は、要素の内容テキストがフィールド型に変換されます。
サポートされている型変換は次のとおりです。
- 文字列はトリミングされますが、変換されません。
- int、long、float、double などのプリミティブ型。
- プリミティブ型の基本的なラッパークラス。
- リスト、セット、およびコレクション。このような場合、xml-content の各要素はコレクションの要素と見なされ、変換を適用して再帰的に解析されます。要素の型が
java.lang.Stringと異なる場合は、完全修飾型名で type 属性を指定することにより、その型を指定します。たとえば、このコードは文字列のArrayListを numbers フィールドに挿入します。<numbers> <element>one</element> <element>two</element> <element>three</element> </numbers>
<numbers> <element>one</element> <element>two</element> <element>three</element> </numbers>Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要素内のテキストは、文字列コンストラクターを持つ任意のオブジェクトに変換できます。文字列以外の型を使用するには、フィールド (この場合は numbers) で element-type を指定します。マップの別の例を次に示します。<numbers> <entry><key>one</key><value>1</value></entry> <entry><key>two</key><value>2</value></entry> <entry><key>three</key><value>3</value></entry> </numbers>
<numbers> <entry><key>one</key><value>1</value></entry> <entry><key>two</key><value>2</value></entry> <entry><key>three</key><value>3</value></entry> </numbers>Copy to Clipboard Copied! Toggle word wrap Toggle overflow - この場合、フィールド要素のそれぞれに、1 つの key と 1 つの value サブ要素がある必要があります。変換規則を再帰的に使用して、これらの両方を解析します。コレクションと同様に、type 属性を指定しなかった場合は、
java.lang.Stringへの変換が意図されていると見なされます。 org.dom4j.Element- その他の型の場合は、文字列コンストラクターが使用されます。
次のクラスを参照してください。
これは、そのクラスの有効な設定です。
14.2.3.2. config-type Bean リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
これは config-type フィールドと同じですが、その場合、プロパティーは "setter" メソッドを介して設定されます。ここでは、プロパティーはフィールドに直接設定されます。同じ変換が適用されます。
14.2.3.3. config-type コンストラクター リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
このメソッドは、委譲 XML 要素のすべての内容を取得し、それらをテキストとして委譲クラスコンストラクターに渡します。
14.2.3.4. config-type configuration-property リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
デフォルトのコンストラクターを使用する場合、このメソッドは委譲 XML 要素のすべての内容を取得し、それをテキストとして
void configure(String); メソッドに渡します。
14.3. 式 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
JSP/JSF EL ライクな式言語のサポートは限定されています。アクション、割り当て、決定条件では、
expression="#{myVar.handler[assignments].assign}" のような式を記述できます。
注記
この式言語の詳細は、次のチュートリアルを参照してください。http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JSPIntro7.html
jPDL と JSF の式言語は似ています。jPDL EL は JSF EL をベースとしていますが、後者とは対照的に、jPDL EL は
#{...} 表記を採用し、メソッドバインディングのサポートを備えています。
コンテキストに応じて、次の暗黙的オブジェクトと同様に、プロセスおよびタスクのインスタンス変数を開始変数として使用できます。
- taskInstance (
org.jbpm.taskmgmt.exe.TaskInstance) - processInstance (
org.jbpm.graph.exe.ProcessInstance) - processDefinition (
org.jbpm.graph.def.ProcessDefinition) - token (
org.jbpm.graph.exe.Token) - taskMgmtInstance (
org.jbpm.taskmgmt.exe.TaskMgmtInstance) - contextInstance (
org.jbpm.context.exe.ContextInstance)
この機能は、JBoss SEAM 環境 (http://www.jboss.com/products/seam) で使用した場合に効果的です。JBPM と SEAM は統合されているため、すべての backed Bean や Enterprise Java Bean などにプロセス定義内からアクセスできるようになります。
14.4. jPDL XML スキーマ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
jPDL スキーマは、プロセスアーカイブの
processdefinition.xml ファイルで使用されるスキーマです。
14.4.1. 検証 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
jPDL XML ドキュメントを解析するとき、jBPM は次の 2 つの条件が満たされると、それをスキーマに対して検証します。
- スキーマは XML ドキュメントで参照されます。
<process-definition xmlns="urn:jbpm.org:jpdl-3.2"> ... </process-definition>
<process-definition xmlns="urn:jbpm.org:jpdl-3.2"> ... </process-definition>Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Xerces パーサーはクラスパスにあります。
注記
jPDL スキーマは
${jbpm.home}/src/java.jbpm/org/jbpm/jpdl/xml/jpdl-3.2.xsd または http://jbpm.org/jpdl-3.2.xsd で確認してください。
14.4.2. process-definition リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| name | 属性 | 任意 | これはプロセスの名前です。 |
| swimlane | 要素 | [0..*] | これはプロセスで使用される swim-lane です。swim-lane はプロセスの役割を表し、タスクの割り当てに使用されます。 |
| start-state | 要素 | [0..1] | これはプロセスの開始状態です。start-state のないプロセスは有効ですが、実行できないことに注意してください。 |
| {end-state|state|node|task-node|process-state|super-state|fork|join|decision} | 要素 | [0..*] | これらはプロセス定義のノードです。ノードのないプロセスは有効ですが、実行できないことに注意してください。 |
| event | 要素 | [0..*] | これはアクションのコンテナーとして機能します。 |
| {action|script|create-timer|cancel-timer} | 要素 | [0..*] | これらは、イベントおよび遷移から参照できるグローバルに定義されたアクションです。これらのアクションを参照するには、名前を指定する必要があることに注意してください。 |
| task | 要素 | [0..*] | これは、アクションなどで使用できるグローバルに定義されたタスクです。 |
| exception-handler | 要素 | [0..*] | これは、このプロセス定義の委譲クラスによって出力されたすべてのエラーに適用される例外ハンドラーのリストです。 |
14.4.3. node リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| {action|script|create-timer|cancel-timer} | 要素 | 1 | これは、このノードの動作を表すカスタムアクションです。 |
| 共通のノード要素 | 「共通のノード要素」 |
14.4.4. 共通のノード要素 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| name | 属性 | required | これはノードの名前です。 |
| async | 属性 | { true | false }、デフォルトは false | true に設定すると、このノードは非同期で実行されます。10章 非同期継続 も併せて参照してください。 |
| transition | 要素 | [0..*] | これは退出遷移です。ノードから退出する各遷移には、個別の名前が *必要* です。名前を持たない遷移は、最大 1 つまで許可されます。指定された最初の遷移は、デフォルト遷移と呼ばれます。遷移を指定せずにノードから退出すると、デフォルトの遷移が取得されます。 |
| event | 要素 | [0..*] | サポートされているイベントタイプは、{node-enter|node-leave} の 2 つです。 |
| exception-handler | 要素 | [0..*] | これは、このプロセスノード内から委譲クラスによって出力されたすべてのバグに適用される例外ハンドラーのリストです。 |
| timer | 要素 | [0..*] | これは、このノードでの実行時間をモニタリングするタイマーを指定します。 |
14.4.5. start-state リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| name | 属性 | 任意 | これはノードの名前です。 |
| task | 要素 | [0..1] | これは、このプロセスの新しいインスタンスを開始するため、またはプロセスのイニシエーターをキャプチャーするために使用されるタスクです。「 開始タスクのスイムレーン 」 を参照 |
| event | 要素 | [0..*] | サポートされているイベントタイプは {node-leave} です。 |
| transition | 要素 | [0..*] | これは退出遷移です。ノードから退出する各遷移には、個別の名前が必要です。 |
| exception-handler | 要素 | [0..*] | これは、このプロセスノード内から委譲クラスによって出力されたすべてのバグに適用される例外ハンドラーのリストです。 |
14.4.6. end-state リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| name | 属性 | required | これは end-state の名前です。 |
| end-complete-process | 属性 | 任意 | end-complete-process が false に設定されている場合、この end-state を完了するトークンのみが完了します。このトークンが最後に終了した子だった場合、親トークンが再帰的に終了します。プロセスインスタンス全体を確実に終了するには、このプロパティーを true に設定します。 |
| event | 要素 | [0..*] | サポートされているイベントタイプは {node-enter} です。 |
| exception-handler | 要素 | [0..*] | これは、このプロセスノード内から委譲クラスによって出力されたすべてのバグに適用される例外ハンドラーのリストです。 |
14.4.7. state リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| 共通のノード要素 | 「共通のノード要素」 を参照 |
14.4.8. task-node リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| signal | 属性 | 任意 | これは {unsynchronized|never|first|first-wait|last|last-wait} で、デフォルトは last です。タスクの完了が プロセスの実行継続 に影響を与える方法を指定します。 |
| create-tasks | 属性 | 任意 | これは {yes|no|true|false} で、デフォルトは true です。ランタイム時の計算で、どのタスクを作成する必要があるかを決定する必要がある場合は、false に設定します。その場合、node-enter にアクションを追加し、そのアクションにタスクを作成して create-tasks を false に設定します。 |
| end-tasks | 属性 | 任意 | これは {yes|no|true|false} で、デフォルトは false です。node-leave で remove-tasks が true に設定されている場合、開いているすべてのタスクが終了します。 |
| task | 要素 | [0..*] | これは、実行がこのタスクノードに到達したときに作成されるタスクです。 |
| 共通のノード要素 | 「共通のノード要素」 を参照 |
14.4.9. process-state リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| sub-process | 要素 | 1 | これは、このノードに関連付けられているサブプロセスです。 |
| variable | 要素 | [0..*] | これは、開始時にスーパープロセスからサブプロセスにデータをコピーする方法と、サブプロセスの完了時にサブプロセスからスーパープロセスにデータをコピーする方法を指定します。 |
| 共通のノード要素 | 「共通のノード要素」 を参照 |
14.4.10. super-state リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| {end-state|state|node|task-node|process-state|super-state|fork|join|decision} | 要素 | [0..*] | これらはスーパーステートのノードです。スーパーステートはネストできます。 |
| 共通のノード要素 | 「共通のノード要素」 を参照 |
14.4.11. fork リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| 共通のノード要素 | 「共通のノード要素」 を参照 |
14.4.12. join リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| 共通のノード要素 | 「共通のノード要素」 を参照 |
14.4.13. decision リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| handler | 要素 | 'handler' 要素または遷移の条件のいずれかを指定する必要があります。 | org.jbpm.jpdl.Def.DecisionHandler 実装の名前 |
| transition conditions | 決定から退出する遷移の属性または要素のテキスト |
すべての遷移には保護条件が含まれる場合があります。決定ノードは、条件を持つ退出遷移を調べ、条件が真である最初の遷移を選択します。
条件が満たされない場合は、デフォルト の遷移が取得されます。デフォルト遷移は、存在する場合は最初の無条件遷移であり、存在しない場合は最初の条件付き遷移です。遷移はドキュメント順に考慮されます。
条件付き ("保護された") 遷移のみが使用可能で、遷移の条件がいずれも true と評価されない場合、例外が出力されます。
| |
| 共通のノード要素 | 「共通のノード要素」 を参照 |
14.4.14. event リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| type | 属性 | required | これは、イベントが配置される要素に対して相対的に表現されるイベントタイプです。 |
| {action|script|create-timer|cancel-timer} | 要素 | [0..*] | これは、このイベントで実行する必要があるアクションのリストです。 |
14.4.15. transition リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| name | 属性 | 任意 | これは遷移の名前です。ノードから退出する各遷移には、個別の名前が *必要* であることに注意してください。 |
| to | 属性 | required | これは宛先ノードの階層名です。階層名の詳細は、「 階層名 」 を参照してください。 |
| condition | 属性または要素のテキスト | 任意 | これは 保護条件 式です。この条件属性 (または子要素) を決定ノードで使用するか、ランタイム時にトークンで使用可能な遷移を計算します。条件は、決定ノードから退出する遷移でのみ許可されます。 |
| {action|script|create-timer|cancel-timer} | 要素 | [0..*] | これらは、この遷移が発生したときに実行されるアクションです。遷移のアクションはイベントに入れる必要がないことに注意してください (イベントは 1 つしかないため)。 |
| exception-handler | 要素 | [0..*] | これは、このプロセスノード内から委譲クラスによって出力されたすべてのバグに適用される例外ハンドラーのリストです。 |
14.4.16. action リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| name | 属性 | 任意 | これはアクションの名前です。アクションに名前を付けると、プロセス定義から検索できます。これは、ランタイムアクションやアクションの宣言を 1 回だけ行う場合に役立ちます。 |
| class | 属性 | ref-name または expression のいずれか | これは、org.jbpm.graph.def.ActionHandler インターフェイスを実装するクラスの完全修飾クラス名です。 |
| ref-name | 属性 | ref-name または class のいずれか | これは参照されるアクションの名前です。参照されるアクションが指定されている場合、このアクションの内容はそれ以上処理されません。 |
| expression | 属性 | expression、class 、または ref-name のいずれか | これは、メソッドに解決される jPDL 式です。「 式 」 も併せて参照してください。 |
| accept-propagated-events | 属性 | 任意 | オプションは {yes|no|true|false} です。デフォルトは yes|true です。false に設定した場合、アクションは、このアクションの要素で発生したイベントでのみ実行されます。詳細は、「 イベントの受け渡し 」 を参照してください。 |
| config-type | 属性 | 任意 | オプションは {field|bean|constructor|configuration-property} です。これは、action-object を構築する方法と、この要素の内容をその action-object の設定情報として使用する方法を指定します。 |
| async | 属性 | {true|false} | 'async="true" は、イベントでトリガーされた場合にのみ、アクション でサポートされます。デフォルト値は false です。これは、アクション が実行のスレッドで実行されることを意味します。true に設定した場合、メッセージがコマンドエグゼキューターに送信され、そのコンポーネントがアクションを別のトランザクションで非同期に実行します。 |
| {content} | 任意 | アクションの内容は、カスタムアクション実装の設定情報として使用できます。これにより、再利用可能な委譲クラスを作成できます。 |
14.4.17. script リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| name | 属性 | 任意 | これはスクリプトアクションの名前です。アクションに名前を付けると、プロセス定義から検索できます。これは、ランタイムアクションやアクションの宣言を 1 回だけ行う場合に役立ちます。 |
| accept-propagated-events | 属性 | 任意 [0..*] | {yes|no|true|false}。デフォルトは yes|true です。false に設定すると、アクションは、このアクションの要素で発生したイベントでのみ実行されます。詳細は、「 イベントの受け渡し 」 を参照してください。 |
| expression | 要素 | [0..1] | Beanshell スクリプト。variable 要素を指定しない場合は、式を script 要素の内容として記述できます (expression 要素タグは省略します)。 |
| variable | 要素 | [0..*] | スクリプトの in 変数。in 変数が指定されていない場合、現在のトークンのすべての変数がスクリプト評価にロードされます。スクリプト評価にロードする変数の数を制限する場合は、in 変数を使用します。 |
14.4.18. expression リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| {content} | Bean シェルスクリプト。 |
14.4.19. variable リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| name | 属性 | required | プロセスの変数名 |
| access | 属性 | 任意 | デフォルトは read,write です。これは、アクセス指定子のコンマ区切りリストです。これまでに使用したアクセス指定子は、read、write、および required のみです。"required" は、タスク変数をプロセス変数に送信する場合にのみ関係します。 |
| mapped-name | 属性 | 任意 | デフォルト設定は変数名です。これは変数名がマップされる名前を指定します。mapped-name の意味は、この要素が使用されるコンテキストに依存します。スクリプトの場合、これは script-variable-name になります。タスクコントローラーの場合、これはタスクフォームパラメーターのラベルになります。プロセス状態の場合、これはサブプロセスで使用される変数名になります。 |
14.4.20. handler リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| expression | 属性 | expression または class のいずれか | jPDL 式。返された結果は toString () メソッドで文字列に変換されます。結果の文字列が退出遷移の 1 つと一致する必要があります。「 式 」も併せて参照してください。 |
| class | 属性 | class または ref-name のいずれか | org.jbpm.graph.node.DecisionHandler インターフェイスを実装するクラスの完全修飾クラス名。 |
| config-type | 属性 | 任意 | {field|bean|constructor|configuration-property}。action-object を構築する方法と、この要素の内容をその action-object の設定情報として使用する方法を指定します。 |
| {content} | 任意 | ハンドラーの内容は、カスタムハンドラー実装の設定情報として使用できます。これにより、再利用可能な委譲クラスを作成できます。 |
14.4.21. timer リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| name | 属性 | 任意 | タイマーの名前。名前が指定されていない場合は、包含するノードの名前が使用されます。すべてのタイマーには一意の名前が必要であることに注意してください。 |
| duedate | 属性 | required | タイマーの作成からタイマーの実行までの期間を指定する時間幅 (必要に応じて営業時間で表します)。この構文については、「 期間 」 を参照してください。 |
| repeat | 属性 | 任意 | {duration | 'yes' | 'true'}。duedate にタイマーを実行した後、'repeat' により、必要に応じてノードから退出するまでタイマー実行を繰り返す期間を指定します。yes または true を指定した場合、duedate と同じ期間が繰り返されます。この構文については、「 期間 」 を参照してください。 |
| transition | 属性 | 任意 | タイマーイベントが発生し、アクション (存在する場合) が実行された後、タイマーが実行されるときに取得される遷移の名前。 |
| cancel-event | 属性 | 任意 | この属性は、タスクのタイマーでのみ使用されます。タイマーをキャンセルするイベントを指定します。デフォルトでは、これは task-end イベントですが、たとえば task-assign や task-start にも設定できます。属性のコンマ区切りリストで指定することで、cancel-event タイプを組み合わせることができます。 |
| {action|script|create-timer|cancel-timer} | 要素 | [0..1] | このタイマーが起動したときに実行する必要があるアクション。 |
14.4.22. create-timer リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| name | 属性 | 任意 | タイマーの名前。この名前は、cancel-timer アクションでタイマーをキャンセルするために使用できます。 |
| duedate | 属性 | required | タイマーの作成からタイマーの実行までの期間を指定する時間幅 (必要に応じて営業時間で表します)。この構文については、「 期間 」 を参照してください。 |
| repeat | 属性 | 任意 | {duration | 'yes' | 'true'}。duedate にタイマーを実行した後、'repeat' により、必要に応じてノードから退出するまでタイマー実行を繰り返す期間を指定します。yes または true を指定した場合、duedate と同じ期間が繰り返されます。この構文については、「 期間 」 を参照してください。 |
| transition | 属性 | 任意 | タイマーイベントが発生し、アクション (存在する場合) が実行された後、タイマーが実行されるときに取得される遷移の名前。 |
14.4.23. cancel-timer リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| name | 属性 | 任意 | キャンセルするタイマーの名前。 |
14.4.24. task リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| name | 属性 | 任意 | タスクの名前。名前付きのタスクは、TaskMgmtDefinition を介して参照および検索できます。 |
| blocking | 属性 | 任意 | {yes|no|true|false}。デフォルトは false です。blocking を true に設定した場合、タスクが完了していないときにノードから退出することはできません。false (デフォルト) に設定すると、トークンのシグナルは実行を継続してノードから退出することができます。blocking は通常、ユーザーインターフェイスによって強制されるため、デフォルトは false に設定されています。 |
| signalling | 属性 | 任意 | {yes|no|true|false}。デフォルトは true です。signalling を false に設定した場合、このタスクがトークンの継続をトリガーする機能を持つことはありません。 |
| duedate | 属性 | 任意 | 11章 ビジネスカレンダー で説明されているように、絶対時間または営業時間で表される期間です。 |
| swimlane | 属性 | 任意 | スイムレーンへの参照。タスクにスイムレーンが指定されている場合、割り当ては無視されます。 |
| priority | 属性 | 任意 | {highest, high, normal, low, lowest} のいずれか。または、優先順位として任意の整数を指定できます。参考: (最高 = 1、最低 = 5) |
| assignment | 要素 | 任意 | タスクの作成時にアクターにタスクを割り当てる委譲を記述します。 |
| event | 要素 | [0..*] | サポートされているイベントタイプは、{task-create|task-start|task-assign|task-end} です。task-assign については、TaskInstance に非永続プロパティー previousActorId が追加されています。 |
| exception-handler | 要素 | [0..*] | このプロセスノードでスローされる委譲クラスによってスローされるすべての例外に適用される例外ハンドラーのリスト。 |
| timer | 要素 | [0..*] | このタスクの実行時間をモニタリングするタイマーを指定します。タスクタイマーに特化した cancel-event を指定できます。デフォルトでは cancel-event は task-end ですが、task-assign や task-start などにカスタマイズできます。 |
| controller | 要素 | [0..1] | プロセス変数をタスクフォームパラメーターに変換する方法を指定します。タスクフォームパラメーターは、タスクフォームをユーザーに表示するためにユーザーインターフェイスによって使用されます。 |
14.4.25. スイムレーン リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| name | 属性 | required | スイムレーンの名前。スイムレーンは、TaskMgmtDefinition を介して参照および検索できます。 |
| assignment | 要素 | [1..1] | このスイムレーンの割り当てを指定します。割り当ては、このスイムレーンで最初のタスクインスタンスが作成されたときに実行されます。 |
14.4.26. 割り当て リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| expression | 属性 | 任意 | 歴史的な理由から、この属性式は、jPDL 式を 参照するものではなく、jBPM アイデンティティーコンポーネントの割り当て式です。jBPM アイデンティティーコンポーネント式の記述方法の詳細は、「割り当て式」 を参照してください。この実装は、jbpm アイデンティティーコンポーネントに依存していることに注意してください。 |
| actor-id | 属性 | 任意 | actorId。pooled-actors と組み合わせて使用できます。actor-id は式として解決されます。したがって、actor-id="bobthebuilder" のように、固定の actorId を参照できます。または、actor-id="myVar.actorId" のように、文字列を返すプロパティーまたはメソッドを参照できます。これは、タスクインスタンス変数 "myVar" で getActorId メソッドを呼び出します。 |
| pooled-actors | 属性 | 任意 | actorId のコンマ区切りリスト。actor-id と組み合わせて使用できます。プールされたアクターの固定セットは、pooled-actors="chicagobulls, pointersisters" のように指定できます。pooled-actors は式として解決されます。そのため、返すべきプロパティーまたはメソッド、String[]、コレクション、またはプールされたアクターのコンマ区切りリストを参照することもできます。 |
| class | 属性 | 任意 | org.jbpm.taskmgmt.def.AssignmentHandler の実装の完全修飾クラス名。 |
| config-type | 属性 | 任意 | {field|bean|constructor|configuration-property}。assignment-handler-object を構築する方法と、この要素の内容をその assignment-handler-object の設定情報として使用する方法を指定します。 |
| {content} | 任意 | assignment-element の内容は、AssignmentHandler 実装の設定情報として使用できます。これにより、再利用可能な委譲クラスを作成できます。 |
14.4.27. Controller リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| class | 属性 | 任意 | org.jbpm.taskmgmt.def.TaskControllerHandler の実装の完全修飾クラス名。 |
| config-type | 属性 | 任意 | {field|bean|constructor|configuration-property}。これは、assignment-handler-object を構築する方法と、この要素の内容をその assignment-handler-object の設定情報として使用する方法を指定します。 |
| {content} | これは、コントローラーの内容か、指定されたタスクコントローラーハンドラーの設定です (class 属性が指定されている場合。タスクコントローラーハンドラーが指定されていない場合、内容は variable 要素のリストである必要があります)。 | ||
| variable | 要素 | [0..*] | class 属性でタスクコントローラーハンドラーが指定されていない場合、controller 要素の内容は変数のリストである必要があります。 |
14.4.28. sub-process リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| name | 属性 | required | 呼び出すサブプロセスの名前。String として評価される必要がある EL 式を指定できます。 |
| version | 属性 | 任意 | 呼び出すサブプロセスのバージョン。version が指定されていない場合、process-state は特定のプロセスの最新バージョン使用します。 |
| binding | 属性 | 任意 | サブプロセスが解決される瞬間を定義します。オプションは {early|late} です。デフォルトでは early、つまりデプロイメント時に解決されます。binding が late として定義されている場合、process-state は、実行ごとに特定のプロセスの最新バージョンを解決します。late binding は、固定バージョンと組み合わせると意味がありません。したがって、version 属性は binding="late" の場合、無視されます。 |
14.4.29. condition リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
オプションは {content} です。後方互換性のために、expression 属性で条件を入力することもできますが、この属性はバージョン 3.2 以降非推奨となりました。 | required | condition 要素の内容は、ブール値として評価される必要がある jPDL 式です。決定は、(processdefinition.xml ファイルの順序に従って) 式が true に解決される最初の遷移を取得します。どの条件も true に解決されない場合、デフォルトの退出遷移 (最初の遷移) が使用されます。条件は、決定ノードから退出する遷移でのみ許可されます。 |
14.4.30. exception-handler リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 名前 | タイプ | 多重度 | 説明 |
|---|---|---|---|
| exception-class | 属性 | 任意 | これは、この例外ハンドラーと一致する Java の "スロー可能" なクラスの完全修飾名を指定します。この属性が指定されていない場合、すべての例外に一致します (java.lang.Throwable)。 |
| action | 要素 | [1..*] | これは、この例外ハンドラーによってエラーが処理されているときに実行されるアクションのリストです。 |
第15章 ワークフローのテスト駆動開発 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
15.1. ワークフローのテスト駆動開発の概要 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
この章では、拡張機能なしで JUnit を使用してカスタムプロセス定義のユニットテストを実行する方法を説明します。
開発サイクルはできるだけ短期間にします。ソフトウェアソースコードへの変更は (可能であれば、中間のビルド手順なしで) すべて即座に検証します。 次の例は、このような方法で jBPM プロセスを開発およびテストする方法を示しています。
ほとんどのプロセス定義ユニットテストは実行ベースです。各シナリオは 1 つの JUnit テストメソッドで実行します。テストメソッドは、外部トリガー (シグナル) をプロセス実行に送信します。続いて各シグナルの後に検証を行い、プロセスが期待される状態にあることを確認します。
以下は、このようなテストのグラフィカルな表現の例です。ここでは、シンプルなオークションプロセスを使用します。
図15.1 オークションのテストプロセス
次に、メインシナリオを実行するテストを記述します。
15.2. XML ソース リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
実行シナリオを記述する前に、
ProcessDefinition を構成する必要があります。ProcessDefinition オブジェクトを取得する最も簡単な方法は、XML を解析することです。コード補完をオンにして、ProcessDefinition.parse を入力します。さまざまな解析方法が表示されます。ProcessDefinition オブジェクトに解析できる XML を記述するには、次の 3 つの方法があります。
15.2.1. プロセスアーカイブの解析 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プロセスアーカイブ は、プロセスの XML ファイル、つまり
processdefinition.xml を含む ZIP ファイルです。jBPM Process Designer プラグインは、プロセスアーカイブの読み取りと書き込みを行います。
static ProcessDefinition auctionProcess =
ProcessDefinition.parseParResource("org/jbpm/tdd/auction.par");
static ProcessDefinition auctionProcess =
ProcessDefinition.parseParResource("org/jbpm/tdd/auction.par");
15.2.2. XML ファイルの解析 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
processdefinition.xml ファイルを手動で記述するには、JpdlXmlReader を使用します。ant スクリプトを使用して、結果の ZIP ファイルをパッケージ化します。
static ProcessDefinition auctionProcess =
ProcessDefinition.parseXmlResource("org/jbpm/tdd/auction.xml");
static ProcessDefinition auctionProcess =
ProcessDefinition.parseXmlResource("org/jbpm/tdd/auction.xml");
15.2.3. XML 文字列の解析 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
プレーン文字列からインラインでユニットテストの XML を解析します。
付録A GNU Lesser General Public License 2.1 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
付録B 更新履歴 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
| 改訂履歴 | |||
|---|---|---|---|
| 改訂 5.3.1-0.402 | Fri Oct 25 2013 | ||
| |||
| 改訂 5.3.1-0 | Thu Jan 10 2013 | ||
| |||
| 改訂 5.3.0-0 | Thu Mar 29 2012 | ||
| |||
| 改訂 5.2.0-0 | Wed Jun 29 2011 | ||
| |||
| 改訂 5.1.0-0 | Fri Feb 18 2011 | ||
| |||
| 改訂 5.0.2-0 | Wed May 26 2010 | ||
| |||
| 改訂 5.0.1-0 | Tue Apr 20 2010 | ||
| |||
| 改訂 5.0.0-0 | Sat Jan 30 2010 | ||
| |||
法律上の通知 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
Copyright © 2013 Red Hat, Inc.
このドキュメントのテキストと図は、GNU Lesser General Public License (LGPL) バージョン 2.1 に基づいて Red Hat によってライセンスされています。このライセンスのコピーは、付録A GNU Lesser General Public License 2.1 にあります。
このマニュアルは、JBPM 3.2 ユーザーガイドから派生したものです。JBPM の詳細は、プロジェクトの Web サイト (http://www.jboss.org/jbpm) を参照してください。
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, JBoss, MetaMatrix, Fedora, the Infinity Logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
All other trademarks are the property of their respective owners.