JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド

JBoss Enterprise SOA Platform
4.3
JBPM リファレンスガイド
JBoss Enterprise SOA Platform 4.3 CP02 での JBoss jBPM 使用に関す
るガイド
エディッション 1.2
Red Hat Inc.
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
JBoss Enterprise SOA Platform 4.3 CP02 での JBoss jBPM 使用に関す
るガイド
エディッション 1.2
Red Hat Inc.
編集者
Darrin Miso n
Red Hat エンジニアリングコンテンツサービス
dmiso [email protected] m
With contributions from
Shigeaki Wakizaka (Translato r)
Japan JBo ss User Gro up コミュニティ翻訳
Takayo shi Osawa (Translato r)
Japan JBo ss User Gro up
To shiya Ko bayashi (Translato r)
Japan JBo ss User Gro up
法律上の通知
Copyright © 2008 Red Hat, Inc.
T his document is licensed by Red Hat under the Creative Commons Attribution-ShareAlike 3.0 Unported
License. If you distribute this document, or a modified version of it, you must provide attribution to Red
Hat, Inc. and provide a link to the original. If the document is modified, all Red Hat trademarks must be
removed.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section
4d of CC-BY-SA to the fullest extent permitted by applicable law.
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 T orvalds in the United States and other countries.
Java ® is a registered trademark of Oracle and/or its affiliates.
XFS ® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States
and/or other countries.
MySQL ® is a registered trademark of MySQL AB in the United States, the European Union and other
countries.
Node.js ® is an official trademark of Joyent. Red Hat Software Collections is not formally related to or
endorsed by the official Joyent Node.js open source or commercial project.
T he OpenStack ® Word Mark and OpenStack Logo are either registered trademarks/service marks or
trademarks/service marks of the OpenStack Foundation, in the United States and other countries and
are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or
sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.
概要
JBoss SOA Platform 4.3 CP02 での使用の為の JBPM jPDL 3.3 ユーザーガイド
目次
目次
.はじめに
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7. . . . . . . . . .
1. 本書の表記規則
7
1.1. 書体の表記規則
7
1.2. 引用文の表記規則
8
1.3. 注記および警告
9
2. フィードバック
9
. . .1章
第
. . . .はじめに
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
............
1.1. 概要
11
1.2. jPDLスイート
11
1.3. jPDLグラフィカルプロセスデザイナ
12
1.4. jBPMコンソールwebアプリケーション
12
1.5. jBPM コアライブラリ
12
1.6. JBoss jBPMアイデンティティコンポーネント
13
1.7. JBoss jBPMジョブエクセキュータ
13
. . .2章
第
. . . .チュートリアル
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
............
2.1. Hello World サンプル
14
2.2. データベースサンプル
15
2.3. コンテキストサンプル: プロセス変数
16
2.4. タスク割り当てサンプル
17
2.5. カスタムActionサンプル
19
. . .3章
第
. . . グラフ指向プログラミング
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
............
3.1. はじめに
22
3.1.1. ドメイン特化言語
22
3.1.2. グラフ指向言語の機能
23
3.1.2.1. 待機状態のサポート
24
3.1.2.2. グラフ表現
24
3.2. グラフ指向プログラミング
25
3.2.1. グラフ構造
25
3.2.2. 実行
25
3.2.3. プロセス言語
26
3.2.4. Action
28
3.2.5. 同期実行
29
3.2.6. コードサンプル
29
3.3. グラフ指向プログラミングの拡張
30
3.3.1. プロセス変数
30
3.3.2. 並列実行
30
3.3.3. プロセス包含(process composition)
31
3.3.4. 非同期続行
32
3.3.5. 永続化とトランザクション
33
3.3.6. サービスと環境
33
3.4. 考慮事項
33
3.4.1. ランタイムデータの分離
33
3.4.2. GOPと他のテクニックとの比較
34
3.4.3. GOPとペトリネットの比較
34
3.5. アプリケーションドメイン
34
3.5.1. ビジネスプロセス管理 (BPM)
34
3.5.1.1. BPMさまざまな側面
35
3.5.1.2. BPM システムのゴール
35
3.5.2. サービスオーケストレーション
37
1
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
3.6. 組み込みグラフベース言語
3.7. マーケット
3.7.1. 究極のプロセス言語
3.7.2. 分離
37
37
37
38
. . .4.章
第
. . .設定
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4. .0. . . . . . . . . .
4.1. ファクトリのカスタマイズ
43
4.2. 設定プロパティ
43
4.3. 他の設定ファイル
43
4.3.1. Hibernate 設定 XML ファイル
43
4.3.2. Hibernateクエリ設定ファイル
43
4.3.3. ノード型設定ファイル
44
4.3.4. アクション型設定ファイル
44
4.3.5. ビシネスカレンダ設定ファイル
44
4.3.6. 変数マッピング設定ファイル
44
4.3.7. コンバータ設定ファイル
44
4.3.8. デフォルトモジュール設定ファイル
44
4.3.9. プロセスアーカイブパーサ設定ファイル
44
4.4. オプティミスティック並列例外のロギング
44
4.5. オブジェクトファクトリ
45
. . .5章
第
. . . .永続性
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4. .8. . . . . . . . . .
5.1. 永続API
48
5.1.1. 設定フレームワークとの関係
48
5.1.2. JbpmContext の便利メソッド
49
5.1.3. 管理されたトランザクション
51
5.1.4. Hiberante sessionのインジェクション
52
5.1.5. プログラムでのリソースインジェクション
52
5.1.6. 先進的API利用方法
53
5.2. 永続サービス設定
53
5.2.1. DbPersistenceServiceFactory
53
5.2.2. Hibernate sessionファクトリ
54
5.2.3. c3poコネクションプール設定
54
5.2.4. ehcacheキャッシュプロバイダ設定
54
5.3. Hibernateトランザクション
55
5.4. JT Aトランザクション
55
5.5. クエリのカスタマイズ
56
5.6. データベース互換性
56
5.6.1. JDBC接続の分離レベル
57
5.6.2. jBPM DBの変更
57
5.6.3. jBPMデータベーススキーマ
57
5.7. Hibernate クラスの組み合わせ
57
5.8. jBPM Hibernate マッピングファイルのカスタマイズ
58
5.9. 2 次レベルキャッシュ
58
. . .6章
第
. . . .Java
. . . . .EE
. . . アプリケーションサーバー機能
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
............
6.1. エンタープライズ Bean
59
6.2. jBPM エンタープライズ設定
61
6.3. Hibernate エンタープライズ設定
62
6.4. クライアントコンポーネント
64
. . .7章
第
. . . .プロセスのモデリング
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
............
7.1. 概要
68
7.2. プロセスグラフ
68
7.3. ノード
70
7.3.1. ノード責務
70
2
目次
7.3.2. ノードタイプ - タスクノード(task-node)
7.3.3. ノードタイプ - 状態(state)
7.3.4. ノードタイプ - 決定(decision)
7.3.5. ノードタイプ - フォーク(fork)
7.3.6. ノードタイプ - ジョイン(join)
7.3.7. ノードタイプ - ノード(node)
7.4. 遷移(transition)
7.5. Action
7.5.1. Action設定
7.5.2. Action参照
7.5.3. イベント
7.5.4. イベント伝播
7.5.5. スクリプト
7.5.6. カスタムイベント
7.6. 親状態(superstate)
7.6.1. 親状態 - 遷移(transition)
7.6.2. 親状態 - イベント(event)
7.6.3. 階層名(hierarchical name)
7.7. 例外ハンドリング
7.8. プロセス包含(process composition)
7.9. カスタムノードの振る舞い
7.10. グラフ実行(graph execution)
7.11. トランザクション境界(transaction demarcation)
71
71
71
72
72
72
72
73
74
74
74
74
74
75
75
76
76
76
76
77
77
78
79
. . .8章
第
. . . .コンテキスト
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
............
8.1. 変数へのアクセス
82
8.2. 変数の生存期間
82
8.3. 変数永続性
83
8.4. 変数スコープ
83
8.4.1. 変数オーバーローディング
83
8.4.2. 変数オーバーライディング
83
8.4.3. タスクインスタンス変数スコープ
83
8.5. 一時変数
83
8.6. カスタマイズ変数永続性
84
. . .9章
第
. . . .タスク管理
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
............
9.1. タスク
86
9.2. タスクインスタンス
86
9.2.1. タスクインスタンスのライフサイクル
86
9.2.2. タスクインスタンスとグラフ実行
87
9.3. 割り当て
88
9.3.1. 割り当てインターフェース
88
9.3.2. 割り当てデータモデル
88
9.3.3. パーソナルタスクリスト
89
9.3.4. グループタスクリスト
89
9.4. タスクインスタンス変数
90
9.5. タスクコントローラ
90
9.6. スイムレーン
92
9.7. 開始タスクのスイムレーン
92
9.8. タスクイベント
92
9.9. タスクタイマ
93
9.10. タスクインスタンスのカスタマイズ
93
9.11. アイデンティティコンポーネント
93
9.11.1. アイデンティティモデル
94
9.11.2. 割り当て式
94
9.11.2.1. 最初の条件 (First term)
95
3
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
9.11.2.2. 次の条件(Next term)
9.11.3. アイデンティティコンポーネントの削除
95
95
. . .10章
第
. . . . .ドキュメント管理
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
............
. . .11章
第
. . . . .スケジューラ
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
............
11.1. タイマー
98
11.2. スケジューラデプロイメント
98
. . .12章
第
. . . . .非同期継続
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
.............
12.1. コンセプト
100
12.2. サンプル
100
12.3. ジョブエクスキュータ
102
12.4. jBPM's built-in asynchronous messaging
103
. . .13章
第
. . . . .ビジネスカレンダ
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
.............
13.1. Duedate(期限)
105
13.1.1. Duration (期間)
105
13.1.2. 基準日
105
13.1.3. 使用例
105
13.2. カレンダ設定
106
. . .14
第
. .章
. . .Email
. . . . . . サポート
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
.............
14.1. jPDLでのEmail
108
14.1.1. mailアクション
108
14.1.2. メールノード
108
14.1.3. タスクアサインメール
109
14.1.4. タスクリマインダメール
109
14.2. メールでの式
109
14.3. メール受信者の指定
109
14.3.1. 複数の受信者
109
14.3.2. アドレス解決
110
14.4. メールテンプレート
110
14.5. メールサーバーの設定
111
14.6. 差出人アドレスの設定
111
14.7. メールサポートのカスタマイズ
112
14.8. メールサーバー
112
. . .15章
第
. . . . .ロギング
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
.............
15.1. ログ生成
113
15.2. ログの設定
114
15.3. ログ取得
114
15.4. データベースウェアハウシング
115
. . .16章
第
. . . . .jBPM
. . . . . .プロセス定義言語
. . . . . . . . . . . . . . . . . (jPDL)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
.............
16.1. プロセスアーカイブ
116
16.1.1. プロセスアーカイブのデプロイ
116
16.1.2. プロセスバージョニング
116
16.1.3. デプロイ済プロセス定義の変更
117
16.1.4. プロセスインスタンスのマイグレーティング
117
16.1.5. プロセス変換
118
16.2. 委譲
118
16.2.1. jBPMクラスローダ
118
16.2.2. プロセスクラスローダ
118
16.2.3. 委譲設定
118
16.2.3.1. config-type フィールド
119
16.2.3.2. config-type Bean
120
4
目次
16.2.3.3. config-type コンストラクタ
16.2.3.4. config-type configuration-property
16.3. 式
16.4. jPDL XML スキーマ
16.4.1. バリデーション
16.4.2. process-definition
16.4.3. node
16.4.4. 一般的なノード要素
16.4.5. start-state
16.4.6. end-state
16.4.7. state
16.4.8. task-node
16.4.9. process-state
16.4.10. super-state
16.4.11. fork
16.4.12. join
16.4.13. decision
16.4.14. event
16.4.15. transition
16.4.16. アクション
16.4.17. script
16.4.18. 式
16.4.19. variable
16.4.20. handler
16.4.21. timer
16.4.22. create-timer
16.4.23. cancel-timer
16.4.24. タスク
16.4.25. スイムレーン
16.4.26. 割り当て
16.4.27. コントローラ
16.4.28. sub-process
16.4.29. 条件
16.4.30. exception-handler
120
120
120
120
120
121
122
123
123
124
124
124
125
125
126
126
126
127
127
128
129
130
130
131
131
132
133
133
135
135
136
137
137
138
. . .17章
第
. . . . .セキュリティ
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
.............
17.1. T ODO
139
17.2. 認証
139
17.3. 認可
139
. . .18章
第
. . . . .Workflow
. . . . . . . . . .の為の試し運転開発
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14
. . .1. . . . . . . . . .
18.1. Workflow 用の T DD の紹介
141
18.2. XMLソース
142
18.2.1. プロセスアーカイブの構文解析
142
18.2.2. XML ファイルの構文解析
143
18.2.3. XML String の構文解析
143
. . .19章
第
. . . . .プラガブルアーキテクチャ
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14
. . .4. . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14
改訂履歴
. . .6. . . . . . . . . .
5
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
6
はじめに
はじめに
1. 本 書 の 表 記 規 則
本ガイドでは、一部の単語や語句を強調して、特定の情報に対する読者の注意を促すために、以下のよう
な表記規則を採用しています。
本ガイドの PDF および紙書籍版では、Liberation フォントセットの書体を使用しています。また、
Liberation フォントセットがご使用のシステムにインストールされている場合には、HT ML 版もこの書体
で表示されます。インストールされていない場合には、別の対応する書体で表示されます。なお、Red
Hat Enterprise Linux 5 以降のバージョンでは、Liberation フォントセットがデフォルトでインストールさ
れる点に注意してください。
1.1. 書体の表記規則
本ガイドでは、特定の単語や語句に対する注意を促すために、4 つの書体表記規則を採用しています。こ
れらの表記規則および適用される状況は、以下のとおりです。
太字の等幅フォント
シェルコマンド、ファイル名、パスなど、システムへの入力を強調するために使用します。また、キー名
やキーの組み合わせを強調するのにも使用します。以下が例となります。
作業ディレクトリ内の m y_next_bestselling_novel というファイルの内容を表示する
には、シェルプロンプトで cat m y_next_bestselling_novel というコマンドを入力し
て Enter キーを押し、そのコマンドを実行します。
上記の例には、ファイル名、シェルコマンド、キー名が含まれており、すべて太字の等幅フォントで表示
されていますが、文脈で区別することができます。
キーの組み合わせは、プラス記号 (+) で各キーがつながれているので、個別のキーと区別することができ
ます。以下が例となります。
Enter を押してコマンドを実行します。
Ctrl+Alt+F2 を押して仮想ターミナルに切り替えます。
第 1 の例では、押すべき特定のキー名が強調されています。第 2 の例では、3 つのキーを同時に押す、
キーの組み合わせが強調されています。
ソースコードを記載する場合、その段落で言及されるクラス名、メソッド、関数、変数名、戻り値は上記
のように 太字の等幅フォント で表示されます。以下が例となります。
ファイル関連のクラスには、filesystem (ファイルシステム)、file (ファイル)、dir
(ディレクトリ) などがあります。各クラスにそれぞれ独自のパーミッションセットが関連付
けられています。
太字の可変幅フォント
この書体は、アプリケーション名、ダイアログボックスのテキスト、ラベル付きボタン、チェックボック
ス/ラジオボタンのラベル、メニュータイトル、サブメニュータイトルなど、システムで表示される単語や
語句であることを示します。以下が例となります。
メインメニューバーから システム → 設定 → マウス の順で選択し、マウスの設定 を起動
します。全般 タブで 左利き のラジオボタンを選択して 閉じる をクリックし、マウスの主
7
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
ボタンを左から右へ切り替えます (左利きのユーザーが使用するのに適切な設定に変更しま
す)。
gedit ファイルに特殊文字を入力するには、メインのメニューバーから アプリケーション
→ アクセサリ → 文字マップ の順に選択します。次に 文字マップ のメニューバーから 検
索 → 検索 … の順に選択して 検索 フィールドに文字名を入力し、次を検索 をクリックしま
す。検索対象の文字が 文字テーブル に強調表示されます。その文字をダブルクリックして
コピーする文字列 のフィールドに表示されたら、コピー ボタンをクリックします。この後
に編集中のドキュメントに戻り、gedit のメニューバーから 編集 → 貼り付け の順で選択し
ます。
上記のテキストには、アプリケーション名、システム全体のメニュー名と項目、アプリケーション固有の
メニュー名、GUI インターフェースで使用されているボタンおよびテキストが含まれており、これらはす
べて、太字の可変幅フォントで表示されていますが、文脈で区別することができます。
太字斜体の等幅フォント または 太字斜体の可変幅フォント
太字の等幅フォントおよび太字の可変幅フォントに斜体を使用した場合には、いずれも置き換え可能な可
変テキストであることを意味します。斜体は、記載されている通りには入力しないテキスト、あるいは状
況によって変化するテキストを示します。以下が例となります。
ssh を使用してリモートマシンに接続するには、シェルプロンプトで ssh
username@ domain.name と入力します。リモートマシンが exam ple.com で、そのマシン
上のユーザー名が john である場合には、ssh john@ exam ple.com と入力してください。
m ount -o rem ount file-system のコマンドは、指定したファイルシステムを再マウン
トします。たとえば、/hom e ファイルシステムを再マウントするコマンドは m ount -o
rem ount /hom e となります。
現在インストール済みのパッケージのバージョンを確認するには、rpm -q package のコマ
ンドを使用します。その結果、次のような出力が返されます: package-version-release
ユーザー名、ドメイン名、ファイルシステム、パッケージ、バージョン、およびリリースが太字のイタ
リック体で表示されている点に注意してください。これらの語句はプレースホルダーで、コマンドを発行
する際に入力するテキストまたはシステムによって表示されるテキストのいずれかです。
斜体は、著作物のタイトルを表すという標準的な用途の他に、重要な用語の初出時にも使用されます。以
下が例となります。
Publican は DocBook の出版システムです。
1.2. 引用文の表記規則
端末の出力とソースコードは、周囲のテキストとは視覚的に区切られて表示されます。
端末に送信される出力は、ローマン体の等幅フォント を使用して以下のように表示されます。
books
books_tests
Desktop
Desktop1
documentation
downloads
drafts
images
mss
notes
photos
scripts
stuff
svgs
svn
ソースコードの表示にも ローマン体の等幅フォント が使用されますが、以下のような構文強調表示が追
加されます。
8
はじめに
package org.jboss.book.jca.ex1;
import javax.naming.InitialContext;
public class ExClient
{
public static void main(String args[])
throws Exception
{
InitialContext iniCtx = new InitialContext();
Object
ref
= iniCtx.lookup("EchoBean");
EchoHome
home
= (EchoHome) ref;
Echo
echo
= home.create();
System.out.println("Created Echo");
System.out.println("Echo.echo('Hello') = " + echo.echo("Hello"));
}
}
1.3. 注記および警告
本ガイドでは、見落としがちな情報に注意を促すために、次にあげる 3 つの視覚的スタイルを使用してい
ます。
注記
注記には、対象のタスクに関するヒント、ショートカット、その他のアプローチなどを記載してい
ます。注記を無視しても、悪影響はありませんが、作業を効率的に行うためのコツを見逃してしま
う可能性があります。
重要
重要の欄には、現行セッションのみに適用される設定の変更や、更新を適用するのに再起動が必要
なサービスなど、見落としがちな情報を記載しています。「重要」と記載された事項を無視して
も、データ損失などには至りませんが、作業が思ったようにスムーズに進まなくなる可能性があり
ます。
警告
警告は、無視しないでください。警告を無視すると、データ損失が発生する可能性が非常に高くな
ります。
2. フ ィ ー ド バ ッ ク
本ガイドに誤植を見つけられた場合や本ガイドの改善案をお持ちの場合はぜひお知らせください。
Bugzilla http://bugzilla.redhat.com/bugzilla/ にて、 Product には JBoss Enterprise SOA Platform. を選
びレポートの提出をお願いいたします。
バグレポートを提出される場合は、 そのガイドの識別子となる SOA_JBPM_Reference_Manual を必ず明
9
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
記して頂くようお願いします。
ドキュメントに関する改善のご意見についてはできるだけ具体的にお願いいたします。 エラーを発見され
た場合は、 セクション番号および該当部分の前後の文章も含めてご報告頂くと照合が容易になります。
10
第1章 はじめに
第 1章 はじめに
JBoss jBPMは、プロセス言語用の柔軟で、拡張可能なフレームワークです。jPDLは共通のフレームワー
クの上部に構築されるプロセス言語であり、タスク、 非同期通信の待機状態、タイマー、自動化アクショ
ンといったものに関してグラフィカルにビジネスプロセスを表現できる、 直感的なプロセス言語です。
これらの操作を結びつけるために、jPDLは最も強力で、拡張可能な制御フローメカニズムを持っていま
す。
jPDLは最小限の依存関係を持ち、Javaライブラリと同様に簡単に使えます。また、極度にスループットが
重要な環境でも J2EE 分散アプリケーションサーバー上でデプロイして利用可能です。
jPDLは、どのようなデータベースでも設定可能であり、 どのようなアプリケーションサーバ上でもデプロ
イ可能です。
1.1. 概 要
中核的なワークフローとBPM機能は、単なるJavaライブラリとしてパッケージされています。 このライ
ブラリは、プロセスを管理および実行するサービスをjPDLデータベースに含んでいます。
図 1.1 jPDLコンポーネント概要
1.2. jPDLス イ ー ト
スイートは、全てのjBPMコンポーネントがバンドルされており、簡単に1回でダウンロードできます。 そ
れには以下のものが含まれています。
config、標準的なJava環境の設定ファイル
db、データベース作成用のSQLスクリプトと互換性情報
designer。 jPDL プロセスとインストールスクリプトを記述する Eclipse プラグイン (これはプレーン
な jPDL ダウンロードには含まれません)。 「jPDLグラフィカルプロセスデザイナ」 を参照してくださ
い。
doc、ユーザーガイドとjavadoc
サンプル
lib。 jbpm が依存するライブラリ。
server、コンソールウェブアプリケーション内に jbpm を含む設定済みの jboss。(これは簡素な jpdl
11
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
ダウンロードの一部ではありません)
src、jbpmとアイデンティティコンポーネントのJavaソース
設定済 JBossアプリケーションサーバには次のコンポーネントがインストールされています:
jBPM Webコンソール 、Webアーカイブとしてパッケージされます。このコンソールはプロセス参加
者とjBPM管理者が使用できます。
ジョブエクセキュータ 、タイマーとメッセージを実行します。ジョブエグセキュータはコンソール
Web アプリケーションの一部です。ジョブエクセキュータを起動する servlet が存在します。ジョブ
エクセキュータはタイマーと非同期メッセージを監視および実行するスレッドプールを産出します。
データベースの jBPMテーブル :デフォルトは、hypersonicデータベースであり、 jBPMテーブル、プ
ロセスが含まれています。
1つのサンプルプロセス がすでにjBPMデータベースにデプロイされています。
アイデンティティコンポーネント 、アイデンティティコンポーネントライブラリはコンソールWeb
アプリケーションの一部です。アインデンティティコンポーネントはデータベース(JBPM_ID_で始ま
るテーブル)で利用可能です。
1.3. jPDLグ ラ フ ィ カ ル プ ロ セ ス デ ザ イ ナ
jPDL also includes a graphical designer tool. T he designer is a graphical tool for authoring business
processes. It's an eclipse plugin.
グラフィカルデザイナーツールの最も重要な特徴は、これが、 技術開発者の為であると共にビジネスアナ
リストの為の両方への サポートを含んでいることです。これにより、ビジネスプロセス モデリングから
現実的な実装に至るまでスムースな転移が可能に なります。
プラグインは標準の eclipse ソフトウェア更新メカニズムを介して、 インストールの為にローカル更新サ
イト(簡素な zip ファイル)として 使用できます。
1.4. jBPMコ ン ソ ー ル webア プ リ ケ ー シ ョ ン
jBPM コンソールウェブアプリケーションは2つの目的を果たします。1つめは プロセスの実行により生
成されたランタイムタスクと通信するための中央ユーザー インターフェイスとしての役目です。2つめは
ランタイムインスタンスの検査と操作を 可能にする管理及び監視のコンソールとしてです。3つめの機能
としてビジネスアクティビティ モニタリングがあります。これらはプロセス実行に関する統計です。管理
者にとって、 ボトルネックや他の最適化手段を見つけるのに役に立ちます。
1.5. jBPM コ ア ラ イ ブ ラ リ
JBoss jBPMコアコンポーネントは、 プロセス定義の管理とプロセスインスタンス実行のためのランタイ
ム環境を管理する単なるJava(J2SE)ライブラリです。
JBoss jBPM は java ライブラリです。そのため、これはウェブアプリケーション、 swing アプリケーショ
ン、EJB、 ウェブサービス等のいかなる java 環境でも使用する ことができます。jBPM ライブラリはま
た、パッケージにしてステートレスセッション EJB として提示することもできます。これにより、極度に
高いスループットのための クラスター化したデプロイと拡張性が可能になります。ステートレスセッショ
ン EJB は、 J2EE 1.3 に対して書かれるため、どのアプリケーションサーバー上でもデプロイ可能です。
使用する機能に応じて、 ライブラリ jbpm -jpdl.jar は Hibernate、 dom4j などのサードパーティライ
ブラリへの依存関係を持ちます。 実際に使用する場合にこれらの依存ライブラリのみが必要となるように
細心の注意が払われました。
jBPMは自身の永続性のために、内部的にHibernateを利用しています。 典型的なO/Rマッピングという面
12
第1章 はじめに
はあるとして、Hibernateは異なるデータベースのSQL方言を吸収しますので、 jBPMを、すべてのデータ
ベース上(HibernateサポートDB)で利用できるように移植可能にします。
T he JBoss jBPM API can be accessed from any custom Java software in your project, like e.g. your web
application, your EJB's, your web service components, your message driven beans or any other Java
component.
1.6. JBoss jBPMア イ デ ン テ ィ テ ィ コ ン ポ ー ネ ン ト
JBoss jBPM はユーザやその他の組織情報を含むどのような企業案内にも統合可能です。 しかし、組織的
な情報コンポーネントが取得できないプロジェクトの場合は、JBoss jBPM が、この コンポーネントを含
んでいます。 アイデンティティコンポーネントで使用されるモデルは、 従来の servlet、EJB、 および
portlet モデルなどより多様です。
詳細については、 「アイデンティティコンポーネント」 を参照してください。
1.7. JBoss jBPMジ ョ ブ エ ク セ キ ュ ー タ
JBoss jBPM ジョブスケジューラは標準的な Java 環境でジョブを監視および実行するコンポーネントで
す。ジョブはタイマーと非同期メッセージに対して使用されます。エンタープライズ環境では、この目的
で JMS と EJB T imerSerive を使用できます。ただし、ジョブエクセキュータは標準的な環境で使用しま
す。
ジョブエクセキュータは、コアjbpm-jpdlライブラリにパッケージされています。しかしながら、 それは、
次のどちらかひとつの環境にデプロイされていなけれななりません。 ジョブエクセキュータを起動するよ
うJbpmT hreadsServletを設定した環境、もしくは、 別のJVMを起動し、そこでジョブエクセキュータス
レッドを実行した環境のどちらかです。
13
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
第 2章 チュートリアル
このチュートリアルでは、 jPDL での基本的なプロセス構築とプロセス実行を管理する API の使用方法を
お見せしましょう。
このチュートリアルは、いくつかのサンプルを使って説明しています。 そのサンプルでは、特定のトピッ
クに焦点をあて、多くのコメントを含んでいます。 そのサンプルは jBPM ダウンロードパッケージの中の
src/java.exam ples ディレクトリにあります。
学習する最良の方法は、プロジェクトを作成し、 提供されているサンプルに対して、変更を加えて、試す
ことです。
jBPM includes a graphical designer tool for authoring the XML that is shown in the examples. You don't
need the graphical designer tool to complete this tutorial.
2.1. Hello World サ ン プ ル
A process definition is a directed graph, made up of nodes and transitions. T he hello world process has
3 nodes. T o see how the pieces fit together, we're going to start with a simple process without the use
of the designer tool. T he following picture shows the graphical representation of the hello world process:
図 2.1 hello world プロセスグラフ
14
第2章 チュートリアル
public void testHelloWorldProcess() {
// This method shows a process definition and one execution
// of the process definition. The process definition has
// 3 nodes: an unnamed start-state, a state 's' and an
// end-state named 'end'.
// The next line parses a piece of xml text into a
// ProcessDefinition. A ProcessDefinition is the formal
// description of a process represented as a java object.
ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
"<process-definition>" +
" <start-state>" +
"
<transition to='s' />" +
" </start-state>" +
" <state name='s'>" +
"
<transition to='end' />" +
" </state>" +
" <end-state name='end' />" +
"</process-definition>"
);
// The next line creates one execution of the process definition.
// After construction, the process execution has one main path
// of execution (=the root token) that is positioned in the
// start-state.
ProcessInstance processInstance =
new ProcessInstance(processDefinition);
// After construction, the process execution has one main path
// of execution (=the root token).
Token token = processInstance.getRootToken();
// Also after construction, the main path of execution is positioned
// in the start-state of the process definition.
assertSame(processDefinition.getStartState(), token.getNode());
// Let's start the process execution, leaving the start-state
// over its default transition.
token.signal();
// The signal method will block until the process execution
// enters a wait state.
// The process execution will have entered the first wait state
// in state 's'. So the main path of execution is now
// positioned in state 's'
assertSame(processDefinition.getNode("s"), token.getNode());
// Let's send another signal. This will resume execution by
// leaving the state 's' over its default transition.
token.signal();
// Now the signal method returned because the process instance
// has arrived in the end-state.
assertSame(processDefinition.getNode("end"), token.getNode());
}
2.2. デ ー タ ベ ー ス サ ン プ ル
jBPM の基本機能の一つとして、待機状態にある時に、プロセスの実行状態をデータベースに永続する機
15
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
能があります。 次のサンプルでは、プロセスインスタンスをどのように jBPM データベースに保存するか
をお見せします。 また、このサンプルは、よくある状況も示唆しています。 つまり、切り離されたメ
ソッドが異なるユーザーコードに作成されている場合です。 例えば、ある Web アプリケーションのユー
ザーコードで、プロセスを開始し、 そのプロセスインスタンスをデータベース内で永続化します。 後
で、メッセージ駆動 Bean が、そのプロセスインスタンスを読み込んで、その実行処理を再開させます。
jBPM永続性の詳細は、5章永続性を参照してください。
2.3. コ ン テ キ ス ト サ ン プ ル : プ ロ セ ス 変 数
プロセス実行中、プロセス変数は、コンテキスト情報を含んでいます。 プロセス変数
は、java.util.Map に類似しており、 変更可能な名称を、java オブジェクトの値とマッピングしま
す。 プロセス変数は、プロセスインスタンスの一部として永続されます。 簡単にするために、このサン
プルでは、 永続処理を利用せずに、プロセス変数を扱う API だけお見せします。
変数の詳細については、8章コンテキスト を参照してください。
16
第2章 チュートリアル
// This example also starts from the hello world process.
// This time even without modification.
ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
"<process-definition>" +
" <start-state>" +
"
<transition to='s' />" +
" </start-state>" +
" <state name='s'>" +
"
<transition to='end' />" +
" </state>" +
" <end-state name='end' />" +
"</process-definition>"
);
ProcessInstance processInstance =
new ProcessInstance(processDefinition);
// Fetch the context instance from the process instance
// for working with the process variables.
ContextInstance contextInstance =
processInstance.getContextInstance();
// Before the process has left the start-state,
// we are going to set some process variables in the
// context of the process instance.
contextInstance.setVariable("amount", new Integer(500));
contextInstance.setVariable("reason", "i met my deadline");
//
//
//
//
//
From now on, these variables are associated with the
process instance. The process variables are now accessible
by user code via the API shown here, but also in the actions
and node implementations. The process variables are also
stored into the database as a part of the process instance.
processInstance.signal();
// The variables are accessible via the contextInstance.
assertEquals(new Integer(500),
contextInstance.getVariable("amount"));
assertEquals("i met my deadline",
contextInstance.getVariable("reason"));
2.4. タ ス ク 割 り 当 て サ ン プ ル
In the next example we'll show how you can assign a task to a user. Because of the separation between
the jBPM workflow engine and the organizational model, an expression language for calculating actors
would always be too limited. T herefore, you have to specify an implementation of AssignmentHandler for
including the calculation of actors for tasks.
17
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
public void testTaskAssignment() {
// The process shown below is based on the hello world process.
// The state node is replaced by a task-node. The task-node
// is a node in JPDL that represents a wait state and generates
// task(s) to be completed before the process can continue to
// execute.
ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
"<process-definition name='the baby process'>" +
" <start-state>" +
"
<transition name='baby cries' to='t' />" +
" </start-state>" +
" <task-node name='t'>" +
"
<task name='change nappy'>" +
"
<assignment" +
"
class='org.jbpm.tutorial.taskmgmt.NappyAssignmentHandler' />" +
"
</task>" +
"
<transition to='end' />" +
" </task-node>" +
" <end-state name='end' />" +
"</process-definition>"
);
// Create an execution of the process definition.
ProcessInstance processInstance =
new ProcessInstance(processDefinition);
Token token = processInstance.getRootToken();
// Let's start the process execution, leaving the start-state
// over its default transition.
token.signal();
// The signal method will block until the process execution
// enters a wait state.
In this case, that is the task-node.
assertSame(processDefinition.getNode("t"), token.getNode());
//
//
//
//
When execution arrived in the task-node, a task 'change nappy'
was created and the NappyAssignmentHandler was called to determine
to whom the task should be assigned. The NappyAssignmentHandler
returned 'papa'.
// In a real environment, the tasks would be fetched from the
// database with the methods in the org.jbpm.db.TaskMgmtSession.
// Since we don't want to include the persistence complexity in
// this example, we just take the first task-instance of this
// process instance (we know there is only one in this test
// scenario).
TaskInstance taskInstance = (TaskInstance)
processInstance
.getTaskMgmtInstance()
.getTaskInstances()
.iterator().next();
// Now, we check if the taskInstance was actually assigned to 'papa'.
assertEquals("papa", taskInstance.getActorId() );
// Now we suppose that 'papa' has done his duties and mark the task
// as done.
taskInstance.end();
// Since this was the last (only) task to do, the completion of this
// task triggered the continuation of the process instance execution.
18
第2章 チュートリアル
assertSame(processDefinition.getNode("end"), token.getNode());
}
2.5. カ ス タ ム Actionサ ン プ ル
Actionは独自のJavaコードをjBPMプロセスにバインドするメカニズムです。 Actionは自身のノードに関連
可能です。 (もしプロセスのグラフ表示上関係がある場合) もしくは、Actionはイベント上に置くことも可
能です。 例えば、遷移する時、ノードに入場あるいは退場をする時です。 その場合、Actionはグラフ表示
の一部ではありませんが、 プロセス実行中に、イベントが起きた時にActionは実行されます。
We'll start with a look at the action implementation that we are going to use in our example :
MyActionHandler. T his action handler implementation does not do really spectacular things... it just
sets the boolean variable isExecuted to true. T he variable isExecuted is static so it can be
accessed from within the action handler as well as from the action to verify it's value.
アクションの詳細については、 「Action」 を参照してください。
// MyActionHandler represents a class that could execute
// some user code during the execution of a jBPM process.
public class MyActionHandler implements ActionHandler {
// Before each test (in the setUp), the isExecuted member
// will be set to false.
public static boolean isExecuted = false;
// The action will set the isExecuted to true so the
// unit test will be able to show when the action
// is being executed.
public void execute(ExecutionContext executionContext) {
isExecuted = true;
}
}
As mentioned before, before each test, we'll set the static field MyActionHandler.isExecuted to
false;
// Each test will start with setting the static isExecuted
// member of MyActionHandler to false.
public void setUp() {
MyActionHandler.isExecuted = false;
}
We'll start with an action on a transition.
19
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
public void testTransitionAction() {
// The next process is a variant of the hello world process.
// We have added an action on the transition from state 's'
// to the end-state. The purpose of this test is to show
// how easy it is to integrate Java code in a jBPM process.
ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
"<process-definition>" +
" <start-state>" +
"
<transition to='s' />" +
" </start-state>" +
" <state name='s'>" +
"
<transition to='end'>" +
"
<action class='org.jbpm.tutorial.action.MyActionHandler' />" +
"
</transition>" +
" </state>" +
" <end-state name='end' />" +
"</process-definition>"
);
// Let's start a new execution for the process definition.
ProcessInstance processInstance =
new ProcessInstance(processDefinition);
// The next signal will cause the execution to leave the start
// state and enter the state 's'
processInstance.signal();
// Here we show that MyActionHandler was not yet executed.
assertFalse(MyActionHandler.isExecuted);
// ... and that the main path of execution is positioned in
// the state 's'
assertSame(processDefinition.getNode("s"),
processInstance.getRootToken().getNode());
// The next signal will trigger the execution of the root
// token. The token will take the transition with the
// action and the action will be executed during the
// call to the signal method.
processInstance.signal();
// Here we can see that MyActionHandler was executed during
// the call to the signal method.
assertTrue(MyActionHandler.isExecuted);
}
次のサンプルは同じ Action ですが、 今回の Action は enter-nodeノードと leave-node ノードの各イ
ベントに配置しています。 1個しかイベントが持てない T ransition とは対称的に、ノードは2個以上のイ
ベントタイプを持てることに注意してください。 ゆえにノードに配置された Action は event 要素に置か
れる必要があります。
20
第2章 チュートリアル
ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
"<process-definition>" +
" <start-state>" +
"
<transition to='s' />" +
" </start-state>" +
" <state name='s'>" +
"
<event type='node-enter'>" +
"
<action class='org.jbpm.tutorial.action.MyActionHandler' />" +
"
</event>" +
"
<event type='node-leave'>" +
"
<action class='org.jbpm.tutorial.action.MyActionHandler' />" +
"
</event>" +
"
<transition to='end'/>" +
" </state>" +
" <end-state name='end' />" +
"</process-definition>"
);
ProcessInstance processInstance =
new ProcessInstance(processDefinition);
assertFalse(MyActionHandler.isExecuted);
// The next signal will cause the execution to leave the start
// state and enter the state 's'. So the state 's' is entered
// and hence the action is executed.
processInstance.signal();
assertTrue(MyActionHandler.isExecuted);
// Let's reset the MyActionHandler.isExecuted
MyActionHandler.isExecuted = false;
// The next signal will trigger execution to leave the
// state 's'. So the action will be executed again.
processInstance.signal();
// Voila.
assertTrue(MyActionHandler.isExecuted);
21
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
第 3章 グラフ指向プログラミング
3.1. は じ め に
この章は、JBoss jBPMのマニフェストであると考えることができます。 それはJBoss jBPMプロジェクト
のビジョンと現在の戦略と将来の方向をふまえたアイデアの概念全体を与えます。 このビジョンは、明ら
かに、伝統的なアプローチとは異なります。
まず最初に、複数のプロセス言語を前提に考えています。 それら特定のプロセス言語に必要とする異なる
環境と目的があります。
2つ目に、グラフ指向プログラミングは、 すべてのグラフベースのプロセス言語の基本になる新しい実装
テクニックを提供します。
このアプローチの主な利点は、すべての種類のプロセス言語のための、 1つの基盤テクノロジーを定義し
ていることです。
現在のソフトウェア開発は、ドメイン特化言語にさらに依存するようになってきました。 標準的なJava開
発者もちょっとしたドメイン特化言語を利用しています。 様々なフレームワークで入力情報として利用さ
れるXMLファイルも、 ドメイン特化言語といえるかもしれません。
図 3.1 グラフベース言語の位置付け
ワークフロー、BPM、オーケストレーション、及びページフローのためのドメイン特化言語は、有向グラ
フの実行に基づいています。Hibernate マッピングファイルや、IoC 設定などの他のものは違います。グ
ラフ指向プログラミングはグラフの実行に 基づいているドメイン特化言語すべての基礎になります。
グラフ指向プログラミングは簡素なオブジェクト指向プログラミング言語でグラフの定義と実行が 可能な
ことを記述するとても簡単なテクニックです。
In 「アプリケーションドメイン」, we'll cover the most often used process languages that can be
implemented using Graph Oriented Programming like workflow, BPM, orchestration and pageflow.
3.1.1. ドメイン特化言語
各プロセス言語は、ドメイン特化言語 (DSL) といえるかもしれません。 DSL という見方は、開発者に、
いかにプロセス言語が、 純粋なオブジェクト指向プログラミングに関係するのかということを考えさせて
くれます。
T his section might give the impression that we're focussed solely on programming environments. None
is less true. Graph Oriented Programming includes the whole BPM product continuum from API libraries
to fully fledged BPM suite products. BPM suite products are complete software development
environments that are centered around business processes. In that type of products, coding in
programming languages is avoided as much as possible.
22
第3章 グラフ指向プログラミング
ドメイン特化言語の重要な面は、 それぞれの言語が、特定の文法を持っているということです。 その文
法はドメインモデルとして表現されます。 java では、クラス、メソッド、フィールド、コンストラクタな
ど、jPDL では、ノード、遷移、アクションなど、ルールでは、条件、結果などとなります。
DSL の主な考え方は、 特化言語のためにモノを書くとき、開発者がそれらの文法で考えるということで
す。 IDE は、言語の文法を中心に構築されています。そして、モノを書くための異なるエディタがあると
いえます。 例えば、jPDL プロセスは、グラフィカルエディタと XML ソースビューエディタを持っていま
す。 また、同じモノを保存するのにも異なる方法があるといえます。 jPDL に関しては、プロセスをあら
わした XMLファイルまたは直列化されたノードと遷移グラフのオブジェクトグラフかもしれません。 も
う 1つの(理論的)例は Java で、 そのシステム上の java クラスファイルフォーマットが 利用できるで
しょう。 ユーザーがエディタを開始した時に、ソースが生成されます。ユーザーが保存するときにコンパ
イル済クラスも保存されます。
T en years ago, most of a developer's time was spent writing code. Now a shift has taken place towards
learning and using domain specific languages. T his trend will continue and the result is that developers
will have a big choice between frameworks and writing software on the host platform. JBoss SEAM is a
very big step in that direction.
これらのいくつかの言語はグラフの実行に基づいています。 例えば、java のワークフロー用 jPDL、サー
ビスオーケストレーションのための BPEL、SEAM ページフローなどです。 グラフ指向プログラミング
は、これら全てのドメイン特化言語のための共通基盤になります。
将来、それぞれの言語で、 開発者は、開発者にあったエディタを選択することができるようになります。
例えば、熟練プログラマはレスポンスの早いソースファイル形式でjavaを編集することをおそらく好むで
しょう。 しかし、やや経験の少ないプログラマは、 クリックしたり、選択したりで、javaクラスに編集し
てくれる機能などをもつエディタを好むかもしれません。 javaソース編集は、もっとずっと柔軟になるで
しょう。
ドメイン特化言語(プログラム言語含む)の他の見方はソフトウェア構造の見方からくるものです。 オブ
ジェクト指向プログラミング(OOP)はメソッドをデータにグルーピングすることで構造を加えます。 アス
ペクト指向言語(AOP)は横断的関心事を取り出す方法をもたらします。 依存性注入(DI)と制御の逆転を
ベースにしたフレームワークはグラフオブジェクトの結びつけに簡単さをもたらします。 また、グラフ
ベースの実行言語は(ここで取り扱います)グラフ実行関連の処理を組み立てる上での複雑さに取り組む
際に役立ちます。
An intial explanation on Domain Specific Languages (DSL) can be found on Martin Fowler's bliki. But the
vision behind it is better elaborated in Martin's article about 'Language Workbenches'.
3.1.2. グラフ指向言語の機能
多くのグラフ指向プロセス言語があります。 それらには環境と焦点について大きな違いがあります。 例
えば、BPEL は、エンタープライズサービスバス(ESB)アーキテクチャ上にある XML ベースのサービス
オーケストレーションという、 意図されたものがあります。 そして、ページフロープロセス言語は、ど
のように Web アプリケーションのページが遷移されるかを定義するものになるかもしれません。これら
は 2つの完全に異なる環境となります。
Despite all these differences, there are two features that you'll find in almost every process language:
support for wait states and a graphical representation. T his is no coincidence because it's exactly those
two features that are not sufficiently supported in plain Object Oriented (OO) programming languages
like Java.
Graph Oriented Programming is a technique to implement these two features in an OO programming
language. T he dependency of Graph Oriented Programming on OO programming implies that all
concrete process languages, implemented on top of Graph Oriented Programming, will have to be
developed in OOP. But this does not mean that the process languages themselves expose any of this
OOP nature. E.g. BPEL doesn't have any relation to OO programming and it can be implemented on top
23
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
of Graph Oriented Programming.
3.1.2.1. 待機状態のサポート
Java のような、命令型プログラミング言語は、 システムの実行による命令の連続を表現するのに使われ
ます。 待機命令はありません。 命令型言語は、例えばサーバー上のリクエスト-レスポンスサイクルと
いった表現をするのに完璧です。 そのシステムはリクエストを処理する、レスポンスが完了するまで一連
の命令を実行し続けます。
しかし、そのリクエスト処理は基本的には、 大きいシナリオの一部にすぎません。 例えば、顧客が注文
書を発行します。 この注文書は、注文管理者によって有効にされるべきです。 承認後、その情報がERP
システムに入力される必要があります。 サーバーへのたくさんのリクエストは大きいシナリオの一部でし
かありません。
つまり、プロセス言語はより大きなシナリオを表現する言語です。ここで明確にしなければいけない重要
な区別は、 ひとつのシステムとして実行可能なシナリオ(オーケストレーション (orchestration)) と、 複
数システム間のプロトコルを表現できるシナリオ (コレオグラフィー (choreography)) です。 グラフ指向
プログラミング実装テクニックは、 1台のマシンで実行可能なプロセス言語(オーケストレーション) のみ
を ターゲットにします。
So an orchestration process describes the overall scenario in terms of one system. For example: A
process is started when a client submits an order. T he next step in the process is the order manager's
approval. So the system must add an entry in the task list of the order manager and then wait until the
order manager provides the required input. When the input is received, the process continues execution.
Now a message is sent to the ERP system and again this system will wait until the response comes
back.
ひとつのシステムのシナリオ全体を表現するのであれば、 待機状態に対応するメカニズムが必要です。
ほとんどのアプリケーションドメインでは、 実行は待機状態中に永続化されなければいけません。 です
からスレッドのブロックでは十分ではありません。 賢明な Java プログラマは Object.wait( )と
Object.notify() メソッドを考えるかもしれません。 これらは待機状態をシミュレートするのに利用できま
すが、問題はスレッドが永続化できないということです。
Continuations is a technique to make the thread and the context variables able to be persisted. T his
could be a sufficient to solve the wait state problem. But as we will discuss in the next section, also a
graphical representation is important for many of the application domains. And continuations is a
technique that is based on imperative programming, so it's unsuitable for the graphical representation.
つまり、待機状態をサポートする重要な側面は、実行が永続されなければいけないことです。 異なるアプ
リケーションドメインでは実行の永続について異なる要件があるかもしれません。 ほとんどのワークフ
ロー、BPM、オーケストレーションアプリケーションでは、 実行をリレーショナルデータベース内に永続
化されなければいけません。標準的にプロセス実行における状態遷移は、 データベースのひとつのトラン
ザクションと一致します。
3.1.2.2. グラフ表現
ソフトウェア開発のある側面ではグラフベースの方法によって大きな利益があります。 グラフベース言語
の典型的なアプリケーションドメインの 1 つはビジネスプロセス管理 (Business Process Management)
です。 この場合、 ビジネス分析者と開発者の間のコミュニケーションは、ビジネスプロセスのグラフ
ベースダイアグラムを共通の言語として使用することにより改善します。 「ビジネスプロセス管理
(BPM)」 も参照してください。
グラフ表現から得ることが可能なもう1つの側面は、ページフローです。 この場合、ページ、ナビゲー
ション、アクションコマンドは、 グラフィカルな表現の中で示され、そして互いにリンクされます。
グラフ指向プログラミングでは、 いくつかの実行の形式を表現するグラフ図表をターゲットにしていま
24
第3章 グラフ指向プログラミング
す。 それはOOデータ構造の静的なモデルを表現するUMLのクラス図とは明らかに区別できます。
図式表現はOOプログラミングで欠けている機能といえます。 OOプログラムの実行をグラフィカル表現す
る賢明な方法はありません。 つまり、OOプログラムとグラフィカルビューの間に直接的な関係はありま
せん。
グラフ指向プログラミングでは、そのグラフ記述が中心で、 例えば、プロセスのグラフ記述がされている
XMLファイルなどが、実際のソフトウェア成果物です。 グラフィカルビューはソフトウェアの本来、備
わっている一部なので、それは常に同期がとれています。 グラフィカルな要件からソフトウェアの設計に
マニュアル操作で変換する必要はありません。 ソフトウェアはグラフの上で構築されます。
3.2. グ ラ フ 指 向 プ ロ グ ラ ミ ン グ
ここでお見せするのはグラフベース実行言語の実装テクニックです。 そのテクニックとは実行時のグラフ
の解釈に基づいています。 他のグラフ実行のテクニックは、メッセージキューやコード生成に基づいてい
ます。
T his section will explain the strategy on how graph execution can be implemented on top of an OO
programming language. For those who are familiar with design patterns, it's a combination of the
command pattern and the chain of responsibility pattern.
We'll start off with the simplest possible model and then extend it bit by bit.
3.2.1. グラフ構造
まず最初に、グラフ構造は、 NodeとT ransitionクラスで表現されます。 遷移には方向がありますの
で、ノードには入場遷移と退場遷移があります。
図 3.2 Nodeと T ransitionクラス
Node はコマンドであり、execute メソッドを持ちます。 Node のサブクラスは、その ノードタイプに
特定の振る舞いをもたせるために execute メソッドをオーバライド することになります。
3.2.2. 実行
グラフ構造で定義した実行モデルは、 有限の状態マシンや UML 状態図に似ているようにみえるかもしれ
ません。 実際、グラフ指向プログラミングは、それらの種類の振る舞いの実装にだけでなく、 もっと多
くのことに使用可能です。
実行(=トークン)は、Executionクラスで表現できます。 Executionは、現在のNodeの参照を保持しま
す。
図 3.3 Executionクラス
25
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
T ransitionは、Executionを遷移元Nodeからtakeメソッドを持つ遷移先Nodeに渡すことができます。
図 3.4 T ransition取得メソッド
When an execution arrives in a node, that node is executed. T he Node's execute method is also
responsible for propagating the execution. Propagating the execution means that a node can pass the
execution that arrived in the node over one of its leaving transitions to the next node.
図 3.5 ノード実行メソッド
When a node's execute method does not propagate the execution, it behaves as a wait state. Also when
a new execution is created, it is initialized in some start node and then waits for an event.
イベントは、Executionに与えられ、Executionが移動開始を起こすことが可能です。 Executionに与えら
れているイベントが現在のNodeの退場遷移に関係している場合、 Executionは、そのT ransitionを取得し
ます。 Executionは、待機状態として振る舞う別のNodeに入場するまで、伝播し続けます。
図 3.6 Executionイベントメソッド
3.2.3. プロセス言語
今まで、待機状態とグラフ表示の2つの機能がサポートされていることを見てきました。 待機状態中、実
行はグラフの中のノードに位置づきます。 プロセスグラフとその実行処理は永続化可能です。 例えば、
HibernateのようなO/R マッパでリレーショナルデータベースに対して永続化したり、 オブジェクトグラ
フをファイルにシリアライズすることによる永続化です。 ノードと遷移でグラフを構成していて、ゆえに
グラフ表現に直接連携していることもわかります。
プロセス言語は、一組のノード実装以外の何者でもありません。 各々のノード実装はプロセス構築に対応
しています。プロセス構築の正確な振る舞いは、実行メソッドをオーバーライドすることで実装されま
す。
ここでは4つのプロセス構築を行うプロセス言語のサンプルをお見せします。 それは開始状態、決定、タ
26
第3章 グラフ指向プログラミング
スク、そして終了状態です。 このサンプルはjPDL言語とは関係ありません。
図 3.7 プロセス言語サンプル
具象ノードオブジェクトは、 プロセス言語サンプルの中にプロセスグラフを作成するのに利用されます。
図 3.8 サンプルプロセス
プロセスのために新しい実行を作る時、 実行を開始ノードに位置させることから始めます。 イベントを
受信しない限り、実行は開始状態に位置したままです。
27
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
図 3.9 新しい実行
Now let's look at what happens when an event is fired. In this initial situation, we fire the default event
that will correspond with the default transition.
これは、実行プロセスオブジェクトのイベントメソッドが呼び出されることによって行われます。 イベン
トメソッドは、以下の流れで伝播します。 デフォルト退出遷移を見つけ、その遷移上の取得メソッドを呼
び出し、パラメタとして実行そのものを遷移の中で渡します。
T he transition will pass on the execution to the decision node and invoke the execute method. Let's
assume the decision's execute implementation performs a calculation and decides to propagate the
execution by sending the 'yes'-event to the execution. T hat will cause the execution to continue over the
'yes' transition and the execution will arrive in the task 'doubleCheck'.
Let's assume that the execute implementation of the doubleCheck's task node adds an entry into the
checker's task list and then waits for the checker's input by not propagating the execution further.
その実行は、doubleCheckタスクノードに位置しつづけます。 すべてのネストされたメソッド呼び出しで
は、 最上位のイベントメソッドに結果を戻す所にたどり着くまで、処理結果を戻していきます。
図 3.10 An execution in the 'doubleCheck' wait state
3.2.4. Action
いくつかのアプリケーションドメインでは、 ノード以外にプログラミングロジックを含める方法が必須に
なります。 例えば、ビジネスプロセス管理では、これがとても重要な特徴です。ビジネスアナリストはグ
ラフ表現を担当して、開発者はそのグラフを実行可能とする担当になります。 ビジネスアナリストに興味
がない技術的な詳細を開発者がグラフ表現に含ませることは受け入れられません。
Action は、 実行メソッドを持つコマンドでもあります。Actionは、イベントと関連可能です。
実行中に、ノードクラスによって起動される2つの基本的なイベントがあります。 node-
28
第3章 グラフ指向プログラミング
leaveとnode-enterです。 その遷移を伴うイベントとともに、すでにプログラミングロジックをグラ
フ実行にインジェクションする自由は与えられています。
図 3.11 グラフィカルビューでは普通、隠れているアクション
各々のイベントはアクションリストと関連付けができます。 すべてのアクションはイベントが 打ち出さ
れる時に実行されます。
3.2.5. 同期実行
T he default propagation of execution is synchronous. In 「 非同期続行」 we'll see how this default
behavior can be changed.
実行はイベントが実行に送られたときに始まります。この実行は遷移の間に伝播し、ノードに入ります。
そのノードが実行を伝播するよう決定した場合は、退場遷移で take メソッドが呼び出され実行がさらに
伝播します。デフォルトでは、これらすべての伝播がネストされたメソッド呼び出しとして実行されま
す。つまり、元のevent メソッドは、実行が新しい待機状態になったときのみ返されます。したがって、
実行は event メソッドの 1 回の呼び出し中に複数のノード間を移動できます。
通常は、トランザクション内部で signal メソッドが呼び出されます。これは、暗黙的に 1つのトランザク
ションで実行がプロセスグラフの複数のノードを移動できることを意味します。これにより、1つのノー
ドごとに1つのトランザクションが必要なシステムでパフォーマンスが大幅に向上します。
同期実行のもう1つの利点は例外処理のオプションが多いことです。すべてのノードが同期的に実行され
た場合は、実行のすべての伝播がネストされたメソッド呼び出しになります。signal メソッドを呼び出し
たコーラーは signal メソッドが返されたときに問題なく新しい待機状態に到達したことを認知します。
3.2.6. コードサンプル
グラフ指向プログラミングの原則に精通できるように、 以下の 4つの130行未満の コードのクラスが
開発されています。 発想を理解するため単にコードを読むことも、又は 実際にそのコードをいじり始め
たり、自分自身でノードタイプを実装したりすることも できます。
Here's the example code:
Execution.java
Node.java
T ransition.java
Action.java
ソースプロジェクト全体(297k)をダウンロードして、 遊び始めてもいいと思います。 eclipseプロジェク
トを含んでいるので、 単純に、eclipseにプロジェクトとしてimportするだけで先に進めます。 基本的な
実行プロセスのテストクラスと次節で取り扱う高度なグラフ実行コンセプト一式もあります。
29
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
3.3. グ ラ フ 指 向 プ ロ グ ラ ミ ン グ の 拡 張
前節では純粋なグラフ指向プログラミングモデルを簡単な形で紹介しました。 この節では様々なグラフ
ベース言語の側面と、それらの要件に対してどのように利用、拡張ができるのか議論します。
3.3.1. プロセス変数
Process variables maintain the contextual data of a process execution. In an insurance claim process,
the 'claimed amount', 'approved amount' and 'isPaid' could be good examples of process variables. In
many ways, they are similar to the member fields of a class.
グラフ指向プログラミングは、プロセス変数のサポートとあわせて、実行プロセスに関連のあるキーと値
のペアのセットを利用することで、 容易に拡張可能です。 並列実行パス (「並列実行」 参照)と プロセ
ス構成 (「プロセス包含(process composition)」 参照) は、少し複雑になります。 ルールの範囲を設け
ると、 並列パスの場合の実行プロセスもしくは、サブプロセスのプロセス変数の可視性が定義されます。
'Workflow Data Patterns' is an extensive research report on the types of scoping that can be applied to
process variables in the context of sub-processing and concurrent executions.
3.3.2. 並列実行
Suppose that you're developing a 'sale' process with a graph-based process language for workflow.
After the client submitted the order, there is a sequence of activities for billing the client and there's also
a sequence of activities for shipping the items to the client. T he billing activies and shipping activities
can be done in parallel.
In that case, one execution will not be sufficient to keep track of the whole process state. Let's go
through the steps to extend the Graph Oriented Programming model and add support for concurrent
executions.
First, let's rename the execution to an execution path. T hen we can introduce a new concept called a
process execution. A process execution represents one complete execution of a process and it contains
many execution paths.
実行パスは階層的に実行可能です。 それは新しい実行プロセスがインスタンス化される時に、 ひとつの
ルート実行パスが作成されるという意味です。 ルート実行パスが複数の並列な実行パスにフォークされる
時、 そのルートは親で、新しく作成されるすべての実行パスはルートの子供です。 ジョインの実装は、
簡単なものになります。 ジョインの実装は、すべての関係している実行パスがジョインノードに位置して
いるか検証しなければなりません。 もし、検証で問題がない場合、親の実行パスはジョインノードを退場
する実行を再開可能です。
階層的な実行パスと兄弟関係にある実行パスのジョインの実装は、 大部分のユースケースをカバーし、
他の並列な振る舞いは特定な状況下で歓迎されるかもしれません。 例えば、複数の実行パスの合流がひと
つの分岐に関連しているときです。 そのような状況では、 他の、マージする実装とランタイムデータの
組み合わせが求められます。
30
第3章 グラフ指向プログラミング
図 3.12 並列実行パス
Multiple concurrent paths of execution are often mixed up with multi-threaded programming. Especially in
the context of workflow and BPM, these are quite different. A process specifies a state machine.
Consider for a moment a state machine as being always in a stable state and state transitions are
instantaneous. T hen you can interpret concurrent paths of execution by looking at the events that cause
the state transitions. Concurrent execution then means that the events that can be handled are
unrelated between the concurrent paths of execution. Now let's assume that state transitions in the
process execution relates to a database transition (as explained in 「永続化とトランザクション」),
then you see that multi-threaded programming is actually not even required to support concurrent paths
of execution.
3.3.3. プロセス包含 (process composition)
プロセス構成は、スーパープロセスの一部としてサブプロセスを含める機能です。 この高度な機能は、プ
ロセスモデリングの抽象化を可能にします。 ビジネスアナリストにとって、この機能は、大きいモデルを
より小さいブロックに落とすために重要です。
基本的なアイデアは、 スーパープロセスは、サブプロセスの実行全体を表現するノードをグラフ中に持っ
ているということです。 実行が、スーパープロセス中のサブプロセスに入場した時、 いくつかのことを
考える必要があります。
まず最初に、サブプロセス用の新しい実行が作成されます。
任意で、スーパープロセスのプロセス変数として保存されているいくつかの情報は、 スーパープロセ
スの実行から、サププロセスの実行へインジェクションできます。 最も簡単な設定は、 サブプロセス
ノードがスーパープロセス変数からサブプロセス変数にコピーされる変数一式で設定されることで
す。
サブプロセスの開始ノードは、ただひとつの退出遷移を持つ必要があります。 複数退出遷移をサポー
トするプロセス言語は、スーパープロセスのプロセス変数に基づいて、 それら複数遷移の中から一つ
を選択するメカニズムを持たなければいけません。
サブプロセス実行は、開始状態のデフォルト退出遷移に対応するイベントが送られて始まります。
サブプロセスが待機状態に入ったときに、 サブ実行プロセスはサブプロセスノードに位置されて、サブ実
行プロセスは同じ待機状態に入ります。
サブ実行プロセスが終了するとき、 スーパープロセスは続けることができます。 その時は、次の側面に
ついて考える必要があります。
プロセス変数情報は、サブ実行プロセスからスーパープロセスにコピーされなければいけないかもし
31
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
れません。
スーパープロセスは続くはずです。 基本的に、プロセス言語はサブプロセスノードにひとつの退出遷
移だけを許します。 その場合、実行スーパープロセスはサブプロセスのデフォルト退出遷移を経由し
て伝達されます。
In case a sub process node is allowed more than one leaving transition, a mechanism has to be
introduced to select a leaving transition. T his selection can be based on either the sub process
execution's variables or the end state of the sub process (a typical state machine can have multiple
end states).
WS-BPEL は明示的ではなく暗黙的なサブプロセスの概念です。新しいサブプロセスはinvoke によって
起動します。スーパープロセスはサブプロセスが終了するまで待機する receive アクティビティを持ち
ます。したがって、特別なアクティビティの代わりに通常の invoke とreceive が使用されます。
3.3.4. 非同期続行
Above, we saw that the default behavior is to execute processes synchronously until there is a wait
state. And typically this overall state-change is packaged in one transaction. In this section, you'll see
how you can demarcate transaction boundaries in the process language. Asynchronous continuations
means that a process can continue asynchronously. T his means that the first transaction will send a
message. T hat message represents a continuation command. T hen the message receiver executes the
command in a second transaction. T hen the process has continued its automatic execution, but it was
split over 2 transactions.
グラフ指向プログラミングに非同期継続を追加するには、メッセージングシステム(プログラミングロジッ
クと統合し、トランザクションによるメッセージの送受信を可能にするシステム)が必要です。メッセージ
ングシステムは、メッセージ指向ミドルウェア(MOM)とも呼ばれ、Java Message Service (JMS)はこのよ
うなシステムを使用するための標準的なAPIです。
Execution can be continued asynchronously immediately before the node's execute method after
entering the node as shown in 図3.13「非同期の継続」.
Suppose some event caused an execution to start propagating over the graph and now a transition is
about to invoke the execute method on the 'generatePdf' node. Instead of invoking the execute method
on the 'generatePdf' node directly, a new command message is being created with a pointer to the
execution. T he command message should be interpreted as "continue this execution by executing the
node". T his message is sent over the message queue to the command executor. T he command
executor takes the message from the queue and invokes the node's execute method with the execution
as a parameter.
図 3.13 非同期の継続
32
第3章 グラフ指向プログラミング
Note that there are two separate transactions involved now. One transaction that originated from the
original event. T hat transaction contains moving the execution in the 'generatePdf' node and sending the
command message. In a second transaction, the command message was consumed and the node's
execute method was invoked with the execution as a parameter. Between the two transactions, the
execution should be blocked for incoming events.
3.3.5. 永続化とトランザクション
プロセス定義情報(Node、T ransition、Actionなど)と実行情報(Executionなど)はリレーショナルデータ
ベースに保管できます。ORMソリューション(Hibernate/EJB3など)を使用して、データベースレコードと
OOPオブジェクトとのマッピングを実行できます。
すべてのプロセス定義情報は静的です。したがって、メモリにキャッシュできます。これにより、パ
フォーマンスが大幅に向上します。各トランザクションではランタイム実行データのみデータベースから
ロードする必要があります。
A transaction typically corresponds to the event method on the Execution. A transaction starts when an
event is being processed. T he event method will trigger execution to continue until a new wait state is
reached. When that happens, the Execution's event method returns and the transaction can be ended.
T he overall change of the event method invocation is that the Execution has moved it's node pointer
from one node to another. T he ORM solution can calculate the difference between the original database
state and the updated Java objects. T hose changes are then flushed to the database at the end of the
Execution's event method. In our example here this will be a SQL update statement on the execution, that
sets the node pointer to the new (wait-state)node.
hibernate/EJB3などのORMソリューションは、各セッションでさまざまなオブジェクトセットと連携しま
す。これは、暗黙的にNode実装へのすべてのアクセスがシリアル化され、ノードが実行データを使用する
(そしてたとえば静的変数は使用しない)限りスレッドセーフコードを記述する必要がないことを意味しま
す。
3.3.6. サービスと環境
ノードがプラグ可能なサービスを使用したい場合、または新しいノード実装が設計時に不明な新しいサー
ビスを使用したい場合があります。これを受け入れるために、 サービスフレームワークをグラフ指向プロ
グラミングに追加して、ノードが 任意のサービスや設定にアクセスできるようにします。
基本的に2つのオプションがあります。
実行コンテキストオブジェクトを渡す(上記で説明したように渡されたExecutionオブジェクトをラップ
する)
スレッドローカル実行コンテキスト
T he execution context contains access to services that are made available by 'the environment'. T he
environment is the client code (the code that invokes the Execution.event(String) plus an
optional container in which this client code runs.
サービスの例としては、タイマーサービス、非同期メッセージングサービス、データベースサービス
(java.sql.Connection) などがあります。
3.4. 考 慮 事 項
3.4.1. ランタイムデータの分離
33
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
グラフ指向プログラミングでは、定義データ(ノード、遷移、アクション)とランタイムデータ(実行)が明確
に区別されます。
したがって、ノードに入った実行を単に伝播する代わりに、どのノード実装でも実行を表す全体のランタ
イムデータを再配置することを決定できます。これにより、fork.split と join/merge のさまざまな動作を非
常に柔軟に実装できるようになります。
また、定義情報は静的であり変更しません。これは、すべてのパフォーマンス最適化で重要になります。
3.4.2. GOPと他のテクニックとの比較
このセクションでは、グラフ指向プログラミングとグラフベースの実行言語で使用される他の実装テク
ニックを比較します。
MOM ベースの実行エンジンでは、実行はメッセージキューを移動するメッセージによって表されます。
プロセスグラフの各ノードはシステムのメッセージキューによって表されます。実際にはグラフ指向プロ
グラミングは MOM ベースの実行のスーパーセットです。GOP ではデフォルトである待機状態から別の待
機状態に実行を移動する計算が同期的に行われます。プロセス非同期で MOM を使用してどのように 1つ
のステップを作成できるかについて説明する非同期継続拡張については本書の後半で説明します。した
がって、MOM ベースの実行は、すべてのノードが非同期的に実行される点でグラフ指向プログラミング
に似ています。
ワークフロー、BPM、及びオーケストレーションシステムを実装するのに使用する別の テクニックはコー
ド生成です。この方法では、グラフベースのプロセスが Java などの命令型プログラミングロジックに変
換されます。生成されたプログラミングロジックは待機状態の後に提供できる各外部トリガに対するメ
ソッドを持ちます。これらのメソッドは新しい待機状態への遷移を計算します。このテクニックはプロセ
スバージョン能力に 限定されて、実際にはコード生成は実用的ではなくソフトウェア開発プロセスのボト
ルネックとなります。
3.4.3. GOPとペトリネットの比較
学術的な世界では、長年ワークフローとビジネスプロセスモデリングに対するペトリネットに注目してき
ました。この主な理由は、並列実行パスをサポートする数学的に定義されたモデルがペトリネットだけ
だったからです。数学的な基盤に基づき、検証や完全性に関する多くの興味深いアルゴリズムを定義でき
ます。
ペトリネットとグラフ指向プログラミングとの最大の差異はその性質です。ペトリネットは数学的なモデ
ルですが、グラフ指向プログラミングは実装テクニックまたはデザインパターンです。
グラフ指向プログラミングを使用してペトリネットを実装できます。ペトリネットプレースとペトリネッ
ト遷移は2つの異なるノードタイプとして実装できます。ペトリネットアークはGOP遷移に対応します。
ペトリネットトークンはGOP実行に対応します。
ペトリネットの上部で定義されたより高いレベル拡張は、グラフ指向プログラミングでも定義できます。
グラフ指向プログラミング自体はペトリネットで定義された分析アルゴリズムをサポートしません。これ
は、グラフ指向プログラミングは具体的な解釈を持たないからです。分析アルゴリズムは、決定論的な設
計時の解釈を持つモデル上でのみ定義できます。その一方でグラフ指向プログラミングは非決定論的な設
計時の解釈を持つモデルもサポートします。GOP ノード実装はランタイムにどのような種類の計算でも
実行でき、 その時にのみ実行がどのように伝播されるかを決定できます。分析アルゴリズムは、ノード実
装が決定論的な設計時の解釈をノードタイプに提供する具体的なプロセス言語でのみ定義できます。
3.5. ア プ リ ケ ー シ ョ ン ド メ イ ン
3.5.1. ビジネスプロセス管理 (BPM)
34
第3章 グラフ指向プログラミング
3.5.1.1. BPMさまざまな側面
T he goal of BPM is to make an organization run more efficient. T he first step is analyzing and describing
how work gets done in an organization. We defining a business process as "a description of the way
that people and systems work together to get a particular job done". Once business processes are
described, the search for optimizations can begin.
時には、ビジネスプロセスは有機的に発展し、ビジネスプロセス全体を単純に見ると明らかに非効率なも
のを見かけます。ビジネスプロセスを効率的にするよう修正するための調査をビジネスプロセスリエンジ
ニアリング(BPR)と呼びます。 一度、ビジネスプロセスの大部分が自動化されると、統計と監査証跡は、
非効率な部分を見つけ、識別するのに役立ちます。
効率化するもうひとつの方法は、ビジネスプロセスの全体、 もしくは一部をIT を利用しての自動化するこ
とです。
ビジネスプロセスの自動化と変更は、組織をより効率よく運営させる最も一般的な方法です。これらはビ
ジネスプロセス管理全般の一部であることに注意してください。
マネージャは継続的に、仕事をチームメンバで処理できるステップにブレークダウンします。 たとえば、
チーム構成でイベントをまとめるソフトウェア開発マネージャを見ましょう。 その場合、ビジネスプロセ
スの記述はマネージャの頭脳だけによってできるかもしれません。 大企業向けの保険請求の管理のよう
な、他の状況では、 より正式なBPM に対するアプローチが必要になります。
ビジネスプロセスを管理する全体的なメリットは、実行プロセスの数と改善する効率向上を掛け合わせた
積と言えます。 正式なビジネスプロセスを管理するコストには、 ちょっとした取り組みが必要でビジネ
スプロセスの分析、記述、改善、自動化に費やします。このため、どのプロセスを正式に管理/自動化のた
めに選択するかを踏まえてコストは検討するべきです。これは、繰り返す確率が高い手順に注意を払うこ
とを表します。
3.5.1.2. BPM システムのゴール
BPM システムの主な目的はビジネスプロセスの自動化を促進することです。ビジネスプロセス用のソフト
ウェアを構築する場合は、業務の分析者と開発者の 2 つの役割が群を抜きます。小規模なチームでは、こ
れらの 2 つの役割は当然 1人で担うことができます。開発者が実行可能なソフトウェアを作成する一方
で、業務の分析者はビジネスプロセスを調査および記述します。
T raditional BPM suites try to start from the business analyst's model and work their way down towards
executable software. T hey try to minimize the need for technical skills so that the business analyst can
produce executable software. All of this is centralized around the graphical diagram so inevitably,
technical details ripple through in the analyst's world.
35
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
図 3.14 従来の BPMアプローチ
In our vision, the central idea is that the business analyst and the developer communicate in a common
language with the help of the graphical view of the process. T echnical skills will always be necessary
when developing software. T he business analyst is responsible for the graphical view and should not be
forced to deal with technical aspects of the process. Without those technical aspects the process will not
be fully defined and hence it won't be executable. T he developer is responsible for the technical
implementation aspects. T echnical aspects should not require diagram changes.
図 3.15 改善された BPMアプローチ
36
第3章 グラフ指向プログラミング
3.5.2. サービスオーケストレーション
サービスオーケストレーション言語で最も知名度が高いのは BPEL です。サービスオーケストレーション
はエンタープライズサービスバスのコンテキストで参照されます。エンタープライズサービスバスは企業
レベルの中央通信バックボーンです。多くの多様なシステムを統合し、XML テクノロジに基づいていま
す。
エンタープライズサービスバスにサービス A、B、C があるとします。サービスオーケストレーションは
新しいサービスを既存のサービスの機能として記述するためのグラフベースの実行言語です。たとえば、
オーケストレーションスクリプトでは新しいサービス D を既存のサービス A、B、C の機能として記述で
きます。
図 3.16 サービス
3.6. 組 み 込 み グ ラ フ ベ ー ス 言 語
When the BPM engine can be completely integrated into a software development project, including even
the BPM engine's database tables, then we speak of an embedded BPM engine. T hat is the goal we
target with Graph Oriented Programming: a common foundation for implementing graph-based
languages.
3.7. マ ー ケ ッ ト
3.7.1. 究極のプロセス言語
伝統的に、ベンダーは究極のプロセス言語を探していました。アプローチはプロセスを一連の構図として
指定することです。 各構図はグラフ表現があり、ランタイムの振る舞いを持ちます。 言い換えれば、各
構図はプロセスグラフのノードタイプです。 そして、プロセス言語は、単にノード構図と言うことです。
アイデアは、ベンダが、 世界的に応用できるプロセス言語を構成するプロセス構図の最もよいセットを探
していたということです。 このビジョンは今日でもまだ見受けられ、そして、究極プロセス言語探しと呼
ばれています。
私達は、究極のプロセス言語を探そうとすることに焦点をあてるのではなく、 むしろ、異なるシナリオや
環境でのプロセス言語のためのベースとして利用可能な共通の基盤を探すことに、 焦点をあてるべきだと
考えています。 次に示す私たちのグラフ指向プログラミングが、そんな基盤だと分るでしょう。
37
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
3.7.2. 分離
T he current landscape of workflow, BPM and orchestration solutions is completely fragmented. In this
section we'll describe two dimensions in this fragmentation. T he first dimension is called the BPM
product continuum and it's shown in the next picture. T he term was originally coined by Derek Miers and
Paul Harmon in 'T he 2005 BPM Suites Report'.
左側にプログラム言語が見えます。この連続体の側面は IT 開発者をターゲットにしています。 プログラ
ミング言語は、もっとも柔軟で、特定プロジェクトで開発された他のソフトウェアと完全に統合します。
しかし、ビジネスプロセスの実装には、相当量のプログラミングを必要とします。
右側は、BPM スイートです。 これら BPM スイートはビジネスアナリストが利用することをターゲットに
したソフトウェア開発環境です。ソフトウェアはビジネスプロセスの周囲で開発されます。 BPM スイー
トで実行可能なソフトウェアを作る際にプログラミングは不要です。
図 3.17 BPM製品連続体
伝統的な製品は、BPM 製品連続体中に1つの場所を印します。 完全なるために、これらの製品は連続体
の一番右側を目指す傾向があります。 これには問題があります。 なぜなら、OOP ソフトウェアとビジネ
スプロセスを組み合わせるプロジェクトを統合することは、 たいへん難しく、一枚岩のシステムに帰着す
るからです。
グラフ指向プログラミングは、簡素なプログラミング環境でうまく統合される単純なライブラリとして構
築可能です。 一方で、このライブラリはパッケージ化可能で、BPM サーバーにする前に事前デプロイ可
能です。 そして、その他の製品が追加され、完全な BPM スイーツになるために、BPM サーバーと一緒に
パッケージされます。
その結果、グラフ指向プログラミングに基づくソリューションは、連続体全体をターゲットとすることが
可能です。 特定のプロジェクトの要件によりますが、 BPM スイートは、ソフトウェア開発環境での適切
なレベルの統合のために、分離とカスタマイズが可能です。
他の分離の側面は、アプリケーションドメインです。 上記のように、BPM アプリケーションドメイン
は、 サービスオーケストレーション、もしくはページフローとは全く異なります。 また、この面で、伝
統的な製品は、ひとつのアプリケーションドメインをターゲットにします。 ここで、グラフ指向プログラ
ミングは、全ての範囲を取り扱います。
もし、これをグラフで立案すれば、これは現在のマーケット分離にある明らかな洞察を与えます。 グラフ
ベース言語マーケットでは値段は高く、量は少ないです。 合併が開始され、 この技術は、現在、分離さ
れ困惑しているマーケットの展望をみすえた共通基盤になることをターゲットにしています。
38
第3章 グラフ指向プログラミング
図 3.18 分離の2面性
39
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
第 4章 設定
jBPM を設定する最も簡単な方法は、 クラスパスのルートに jbpm .cfg.xm l 設定ファイルを指定するこ
とです。 このファイルがリソースとして存在しない場合は、 jbpm ライブラリに含まれるデフォルトの最
小設定が使用されます (org/jbpm /default.jbpm .cfg.xm l)。 jbpm 設定ファイルが提供された場
合、設定された値がデフォルト値として使用されます。 したがって、 デフォルトの設定ファイルと異な
る部分だけ指定する必要があります。
jBPM の設定は、 java クラス org.jbpm .Jbpm Configuration によって表されています。
JbpmConfiguration を取得する最も簡単な方法は、 シングルトンインスタンスメソッド
Jbpm Configuration.getInstance() を利用することです。
他のソースから設定をロードする場合、Jbpm Configuration.parseXxxx メソッドを利用できます。
static JbpmConfinguration jbpmConfiguration =
JbpmConfinguration.parseResource("my.jbpm.cfg.xml");
JbpmConfigurationは、スレッドセーフなので、staticフィールドとして保持可能です。 すべてのスレッド
は、JbpmConfigurationをJbpmContextオブジェクトのファクトリとして利用可能です。 JbpmContextは
基本的にひとつのトランザクションを表しています。 jbpmContextはコンテキストブロック内でサービス
を有効にします。 コンテキストブロックについて以下に記します。
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
// This is what we call a context block.
// Here you can perform workflow operations
} finally {
jbpmContext.close();
}
Jbpm Contextは、サービスのセットで、jBPMへの設定を可能にしています。 これらサービス
は、jbpm .cfg.xm l設定ファイルで設定可能で、 jBPMをどのようなJava環境でも実行可能とし、その環
境で有効なサービスを利用可能とします。
Here's the default configuration for the JbpmContext:
40
第4章 設定
<jbpm-configuration>
<jbpm-context>
<service name='persistence'
factory='org.jbpm.persistence.db.DbPersistenceServiceFactory' />
<service name='message'
factory='org.jbpm.msg.db.DbMessageServiceFactory' />
<service name='scheduler'
factory='org.jbpm.scheduler.db.DbSchedulerServiceFactory' />
<service name='logging'
factory='org.jbpm.logging.db.DbLoggingServiceFactory' />
<service name='authentication'
factory='org.jbpm.security.authentication.DefaultAuthenticationServiceFactory'
/>
</jbpm-context>
<!-- configuration resource files pointing to default
configuration files in jbpm-{version}.jar -->
<string name='resource.hibernate.cfg.xml' value='hibernate.cfg.xml' />
<!-- <string name='resource.hibernate.properties'
value='hibernate.properties' /> -->
<string name='resource.business.calendar'
value='org/jbpm/calendar/jbpm.business.calendar.properties' />
<string name='resource.default.modules'
value='org/jbpm/graph/def/jbpm.default.modules.properties' />
<string name='resource.converter'
value='org/jbpm/db/hibernate/jbpm.converter.properties' />
<string name='resource.action.types'
value='org/jbpm/graph/action/action.types.xml' />
<string name='resource.node.types'
value='org/jbpm/graph/node/node.types.xml' />
<string name='resource.parsers'
value='org/jbpm/jpdl/par/jbpm.parsers.xml' />
<string name='resource.varmapping'
value='org/jbpm/context/exe/jbpm.varmapping.xml' />
<string name='resource.mail.templates'
value='jbpm.mail.templates.xml' />
<int name='jbpm.byte.block.size' value="1024" singleton="true" />
<bean name='jbpm.task.instance.factory'
class='org.jbpm.taskmgmt.impl.DefaultTaskInstanceFactoryImpl'
singleton='true' />
<bean name='jbpm.variable.resolver'
class='org.jbpm.jpdl.el.impl.JbpmVariableResolver'
singleton='true' />
<string name='jbpm.mail.smtp.host' value='localhost' />
<bean
name='jbpm.mail.address.resolver'
class='org.jbpm.identity.mail.IdentityAddressResolver' singleton='true' />
<string name='jbpm.mail.from.address' value='jbpm@noreply' />
<bean name='jbpm.job.executor' class='org.jbpm.job.executor.JobExecutor'>
<field name='jbpmConfiguration'><ref bean='jbpmConfiguration' /></field>
<field name='name'><string value='JbpmJobExecutor' /></field>
<field name='nbrOfThreads'><int value='1' /></field>
<field name='idleInterval'><int value='5000' /></field>
<field name='maxIdleInterval'><int value='3600000' /></field> <!-- 1 hour ->
<field name='historyMaxSize'><int value='20' /></field>
<field name='maxLockTime'><int value='600000' /></field> <!-- 10 minutes ->
41
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
<field name='lockMonitorInterval'><int value='60000' /></field> <!-- 1
minute -->
<field name='lockBufferTime'><int value='5000' /></field> <!-- 5 seconds ->
</bean>
</jbpm-configuration>
この設定では大きく3つの部分に分けられます。
最初の部分では、 サービス実装のセットで jBPM コンテキストを設定します。 可能な設定オプション
は、 そのサービス実装を取り扱う章で説明されます。
2 つ目は、 すべての設定リソースへの参照マッピングです。 これらリソース参照は、 設定ファイルを
カスタマイズしたい場合、 更新可能です。 通常は、 jbpm -3.x.jar の中にあるデフォルト設定をコ
ピーして、 クラスパスに通します。 そして、このファイルの参照を更新します。 jBPM はこのカスタ
マイズされた設定ファイルを利用します。
3 つ目は、 jBPM で利用されるその他の設定です。 これらの設定オプションは、 そのトピック自身を
扱う章で説明されます。
デフォルト設定されたサービスセットは、単純な web アプリケーション環境と最小の依存関係をターゲッ
トにしています。 永続サービスは、JDBC コネクションを取得し、 その他すべてのサービスは、それら
サービスを実行するために同じコネクションを利用します。 つまり、すべてのワークフロー操作は、トラ
ンザクションマネージャを必要とせず、 JDBC コネクション上で、ひとつのトランザクションに一元化さ
れます。
Jbpm Context は、 ほとんどの共通プロセスの動作のための便利なメソッドが用意されています。
public void deployProcessDefinition(ProcessDefinition processDefinition) {...}
public List getTaskList() {...}
public List getTaskList(String actorId) {...}
public List getGroupTaskList(List actorIds) {...}
public TaskInstance loadTaskInstance(long taskInstanceId) {...}
public TaskInstance loadTaskInstanceForUpdate(long taskInstanceId) {...}
public Token loadToken(long tokenId) {...}
public Token loadTokenForUpdate(long tokenId) {...}
public ProcessInstance loadProcessInstance(long processInstanceId) {...}
public ProcessInstance loadProcessInstanceForUpdate(long processInstanceId) {...}
public ProcessInstance newProcessInstance(String processDefinitionName) {...}
public void save(ProcessInstance processInstance) {...}
public void save(Token token) {...}
public void save(TaskInstance taskInstance) {...}
public void setRollbackOnly() {...}
Note that the XxxForUpdate methods will register the loaded object for auto-save so that you don't
have to call one of the save methods explicitly.
It's possible to specify multiple jbpm -contexts, but then you have to make sure that each jbpm context is given a unique nam e attribute. Named contexts can be retrieved with
Jbpm Configuration.createContext(String nam e);
A service element specifies the name of a service and the service factory for that service. T he service
will only be created in case it's asked for with Jbpm Context.getServices().getService(String
nam e).
ファクトリは、属性の代わりに要素を記述することも可能です。 それは、いくつかの設定情報をファクト
リオブジェクトに注入するのに必要かもしれません。 XMLのパース、生成とオブジェクトの結びつけに責
務を持つコンポーネントは、 オブジェクトファクトリと呼ばれます。
42
第4章 設定
4.1. フ ァ ク ト リ の カ ス タ マ イ ズ
ファクトリのカスタマイズ時の一般的な間違いは、短い表記法と長い表記法を混在させてしまうことで
す。短い表記法の例は、デフォルトの設定ファイルと上記に示されています。例を以下に示します。
<service name='persistence'
factory='org.jbpm.persistence.db.DbPersistenceServiceFactory' />
If specific properties on a service need to be specified, the short notation can't be used, but instead, the
long notation has to be used like this: E.g.
<service name="persistence">
<factory>
<bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
<field name="dataSourceJndiName">
<string value="java:/myDataSource"/>
</field>
<field name="isCurrentSessionEnabled"><true /></field>
<field name="isTransactionEnabled"><false /></field>
</bean>
</factory>
</service>
4.2. 設 定 プ ロ パ テ ィ
jbpm.byte.block.size: 添付ファイルとバイナリ変数は、BLOBではなく固定サイズバイナリオブジェクト
のリストとしてデータベースに保存されます。これにより、異なるデータベース間のポータビリティと
jBPMの全体の組込み容易性が向上します。このパラメータは、固定長チャンクのサイズを制御します。
jbpm.task.instance.factory: タスクインスタンスをどのように作成するかをカスタマイズするには、 こ
のプロパティに完全修飾クラスを指定します。 これは、 T askInstance Bean をカスタマイズし、 新しい
プロパティを T askInstance Bean に追加する場合に必要になることがあります。 「タスクインスタンス
のカスタマイズ」 も参照してください。 指定されたクラスは org.jbpm.taskmgmt.T askInstanceFactory を
実装する必要があります。
jbpm.variable.resolver: jBPMがJSFに類似した式で最初の用語を検索する方法をカスタマイズします。
4.3. 他 の 設 定 フ ァ イ ル
Here's a short description of all the configuration files that are customizable in jBPM.
4.3.1. Hibernate 設定 XML ファイル
このファイルには、Hibernate の設定と Hibernate マッピングリソースファイルへの参照が含まれます。
場所: hibernate.cfg.xm l (jbpm.properties ファイルの jbpm.hibernate.cfg.xml プロパティで他に指定
されていない限り)。 jBPM プロジェクトでは、デフォルトの Hibernate 設定 xml ファイルは
src/config.files/hibernate.cfg.xm l ディレクトリに配置されています。
4.3.2. Hibernateクエリ設定ファイル
このファイルは、jBPM セッションであるorg.jbpm .db.* Session で利用されるHibernateクエリを含
んでいます
43
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
場所: org/jbpm /db/hibernate.queries.hbm .xm l
4.3.3. ノード型設定ファイル
このファイルはXMLノード要素とNode実装クラスのマッピングを含んでいます。
場所: org/jbpm /graph/node/node.types.xm l
4.3.4. アクション型設定ファイル
このファイルはXMLアクション要素とアクション実装クラスとのマッピングを含んでいます。
場所: org/jbpm /graph/action/action.types.xm l
4.3.5. ビシネスカレンダ設定ファイル
業務時間、自由時間の定義を含んでいます。
場所: org/jbpm /calendar/jbpm .business.calendar.properties
4.3.6. 変数マッピング設定ファイル
どのようにプロセス変数の値(javaオブジェクト)が、 jBPM データベースのストレージ変数インスタンスに
変換されるかを指定します。
場所: org/jbpm /context/exe/jbpm .varm apping.xm l
4.3.7. コンバータ設定ファイル
id-to-classname マッピングを記述します。id はデータベースに保存されます。
org.jbpm.db.hibernate.ConverterEnumT ype は、 id をシングルトンオブジェクトにマップするために利用
されます。
場所: org/jbpm /db/hibernate/jbpm .converter.properties
4.3.8. デフォルトモジュール設定ファイル
デフォルトで新しい ProcessDefinition に追加されるモジュールを記述します。
場所: org/jbpm /graph/def/jbpm .default.m odules.properties
4.3.9. プロセスアーカイブパーサ設定ファイル
プロセスアーカイブパーシングのフェーズを記述します。
場所: org/jbpm /jpdl/par/jbpm .parsers.xm l
4.4. オ プ テ ィ ミ ス テ ィ ッ ク 並 列 例 外 の ロ ギ ン グ
When running in a cluster, jBPM synchronizes on the database. By default with optimistic locking. T his
means that each operation is performed in a transaction. And if at the end a collision is detected, then
the transaction is rolled back and has to be handled. E.g. by a retry. So optimistic locking exceptions are
usually part of the normal operation. T he org.hibernate.StateObjectStateException
exceptions that Hibernate throws in that case are are logged with a simple message, 'optimistic locking
failed', instead of an error and a stack trace.
Hibernate itself will log the StateObjectStateException including a stack trace. If you want to get rid of
these stack traces, put the level of
44
第4章 設定
org.hibernate.event.def.AbstractFlushingEventListener to FAT AL. If you use log4j
following line of configuration can be used for that:
log4j.logger.org.hibernate.event.def.AbstractFlushingEventListener=FATAL
If you want to enable logging of the jBPM stack traces, add the following line to your jbpm .cfg.xm l.
<boolean name="jbpm.hide.stale.object.exceptions" value="false" />
4.5. オ ブ ジ ェ ク ト フ ァ ク ト リ
オブジェクトファクトリは、Bean のような xml 設定ファイルにしたがってオブジェクトを作成します。
設定ファイルは、オブジェクトグラフを構成するために、どのようにオブジェクトが作成、 設定、互いの
結びつけの動作を行うのかということを記述します。 オブジェクトファクトリは設定情報、Bean を他 の
Bean に注入できます。
最も簡単な構成では、オブジェクトファクトリは、 以下の設定ファイルから基本タイプと Java Bean を
作成可能です。
<beans>
<bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance"/>
<string name="greeting">hello world</string>
<int name="answer">42</int>
<boolean name="javaisold">true</boolean>
<float name="percentage">10.2</float>
<double name="salary">100000000.32</double>
<char name="java">j</char>
<null name="dusttodust" />
</beans>
ObjectFactory of = ObjectFactory.parseXmlFromAbove();
assertEquals(TaskInstance.class, of.getNewObject("task").getClass());
assertEquals("hello world", of.getNewObject("greeting"));
assertEquals(new Integer(42), of.getNewObject("answer"));
assertEquals(Boolean.TRUE, of.getNewObject("javaisold"));
assertEquals(new Float(10.2), of.getNewObject("percentage"));
assertEquals(new Double(100000000.32), of.getNewObject("salary"));
assertEquals(new Character('j'), of.getNewObject("java"));
assertNull(of.getNewObject("dusttodust"));
リストも設定可能です。
<beans>
<list name="numbers">
<string>one</string>
<string>two</string>
<string>three</string>
</list>
</beans>
同様に Map も、
45
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
<beans>
<map name="numbers">
<entry>
<key><int>1</int></key>
<value><string>one</string></value>
</entry>
<entry>
<key><int>2</int></key>
<value><string>two</string></value>
</entry>
<entry>
<key><int>3</int></key>
<value><string>three</string></value>
</entry>
</map>
</beans>
Bean は、直接フィールドインジェクションするか、 または、プロパティ setter 経由で設定可能です。
<beans>
<bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" >
<field name="name"><string>do dishes</string></field>
<property name="actorId"><string>theotherguy</string></property>
</bean>
</beans>
Beans can be referenced. T he referenced object doesn't have to be a bean, it can be a string, integer or
any other object.
<beans>
<bean name="a" class="org.jbpm.A" />
<ref name="b" bean="a" />
</beans>
Bean は、コンストラクタにより作成可能です。
<beans>
<bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" >
<constructor>
<parameter class="java.lang.String">
<string>do dishes</string>
</parameter>
<parameter class="java.lang.String">
<string>theotherguy</string>
</parameter>
</constructor>
</bean>
</beans>
... または Bean のファクトリメソッドを使用する ...
46
第4章 設定
<beans>
<bean name="taskFactory"
class="org.jbpm.UnexistingTaskInstanceFactory"
singleton="true"/>
<bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" >
<constructor factory="taskFactory" method="createTask" >
<parameter class="java.lang.String">
<string>do dishes</string>
</parameter>
<parameter class="java.lang.String">
<string>theotherguy</string>
</parameter>
</constructor>
</bean>
</beans>
... またはクラスの静的ファクトリメソッドを使用する ...
<beans>
<bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" >
<constructor
factory-class="org.jbpm.UnexistingTaskInstanceFactory"
method="createTask" >
<parameter class="java.lang.String">
<string>do dishes</string>
</parameter>
<parameter class="java.lang.String">
<string>theotherguy</string>
</parameter>
</constructor>
</bean>
</beans>
Each named object can be marked as singleton with the attribute singleton="true". T hat means
that a given object factory will always return the same object for each request. Note that singletons are
not shared between different object factories.
T he singleton feature causes the differentiation between the methods getObject and
getNewObject. T ypical users of the object factory will use the getNewObject. T his means that first
the object factory's object cache is cleared before the new object graph is constructed. During
construction of the object graph, the non-singleton objects are stored in the object factory's object cache
to allow for shared references to one object. T he singleton object cache is different from the plain object
cache. T he singleton cache is never cleared, while the plain object cache is cleared at the start of every
getNewObject method.
47
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
第 5章 永続性
In most scenarios, jBPM is used to maintain execution of processes that span a long time. In this context,
"a long time" means spanning several transactions. T he main purpose of persistence is to store
process executions during wait states. So think of the process executions as state machines. In one
transaction, we want to move the process execution state machine from one state to the next.
プロセス定義は、3つの異なる形式で表現可能です。 つまり、xml、Java オブジェクト、及び jBPMデー
タベースのレコードとして表現可能です。 実行 (=ランタイム) 情報とロギング情報は 2つの形式で表現
可能です。 つまり、Java オブジェクト、jBPM データベースのレコードとして表現可能です。
図 5.1 変換と異なる形式
プロセス定義とプロセスアーカイブのxml表記についての詳細は、16章jBPM プロセス定義言語 (jPDL) を
参照してください。
データベースにプロセスアーカイブをデプロイする方法の詳細については、 「 プロセスアーカイブのデ
プロイ」 を参照してください。
5.1. 永 続 API
5.1.1. 設定フレームワークとの関係
永続 API は、 JbpmContext で一部の便利な永続メソッドを公開することにより、 設定フレームワー
ク [1] と統合されます。 したがって、 永続 API 操作は以下のように jBPM コンテキストブロック内部で呼
び出すことができます。
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
// Invoke persistence operations here
} finally {
jbpmContext.close();
}
設定は、以下の永続サービス宣言を含むと考えられます。 (サンプル設定ファイ
ルsrc/config.files/jbpm .cfg.xm lと同様)
48
第5章 永続性
<jbpm-configuration>
<jbpm-context>
<service name='persistence'
factory='org.jbpm.persistence.db.DbPersistenceServiceFactory' />
</jbpm-context>
</jbpm-configuration>
5.1.2. JbpmContext の便利メソッド
最も、よく利用される3つの永続操作は、以下のとおりです。
プロセスのデプロイ
プロセスの新規実行
実行の継続
最初に、プロセス定義のデプロイです。 基本的には、グラフィカルプロセスデザイナもしくは、
deployprocess antタスクのデプロイプロセスによって行われます。 しかし、ここではこれがどのよう
にJava コードで行われるかを理解します。
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
ProcessDefinition processDefinition = ...;
jbpmContext.deployProcessDefinition(processDefinition);
} finally {
jbpmContext.close();
}
新しいプロセス実行作成のために、 どのプロセス定義がプロセス実行のインスタンスになるかを指定しな
ければなりません。 この指定の最も一般的な方法は、 プロセスの名前で参照し、jBPMにデータベースに
ある最新バージョンのプロセスを見つけてもらうことです。
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
String processName = ...;
ProcessInstance processInstance =
jbpmContext.newProcessInstance(processName);
} finally {
jbpmContext.close();
}
プロセス実行の継続のために、 プロセスインスタンス、トークン、タスクインスタンスをデータベースか
ら取り出し、 POJO jBPM オブジェクトのメソッドを呼び出し、その後にプロセスインスタンスの更新を
データベースに再び保管します。
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
long processInstanceId = ...;
ProcessInstance processInstance =
jbpmContext.loadProcessInstance(processInstanceId);
processInstance.signal();
jbpmContext.save(processInstance);
} finally {
jbpmContext.close();
}
JbpmContextのxxxForUpdateメソッドを利用すれば、 jbpmContext.saveの明示的な呼び出しは、
49
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
jbpmContextのクローズ処理中に自動的に行われるために、 必ずしも必要ではないことに注意してくださ
い。 例えば、タスクインスタンスが完了したことをjBPMに知らせたい場合です。 タスクインスタンス終
了は、継続のための実行を起動することが可能です。 従って、タスクインスタンスに関連するプロセスイ
ンスタンスは保管される必要があることに注意してください。 最も便利な方法は、
loadT askInstanceForUpdateメソッドを利用することです。
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
long taskInstanceId = ...;
TaskInstance taskInstance =
jbpmContext.loadTaskInstanceForUpdate(taskInstanceId);
taskInstance.end();
} finally {
jbpmContext.close();
}
バックグラウンド情報になりますが、 次は、jBPMがどのように永続性を管理し、Hibernateを利用してい
るかを説明したものです。
Jbpm Configurationは、ServiceFactoryのセットを維持します。 ServiceFactoryは上記のとお
り、jbpm .cfg.xm lで設定され、遅延ロードされます。 DbPersistenceServiceFactoryは、最初
に必要になったときのみインスタンス化されます。 その後、serviceFactory
は、Jbpm Configurationで維持されます。 DbPersistenceServiceFactoryは、hibernate
のSessionFactoryを管理します。 Hibernateの SessionFactoryもまた、初めて要求があったときに、
遅延ロードで作成されます。
50
第5章 永続性
図 5.2 永続関連クラス
jbpm Configuration.createJbpm Context() の呼び出し中、 Jbpm Context のみが作成されま
す。 その時点では、永続初期処理として、それ以上のことはしません。 Jbpm Context は、 最初の要求
でインスタンス化された DbPersistenceService を管理します。 DbPersistenceService は、
Hibernateのsession を管理します。 その DbPersistenceService にある Hibernate の session もま
た、遅延ロードで作成されます。 結果として、Hibernateのsession は最初に永続メソッドの呼び出しが
されたときにのみオープンされます。 それ以前にオープンされることはありません。
5.1.3. 管理されたトランザクション
管理トランザクションのもっとも一般的なシナリオは、 JBoss のような JEE アプリケーションサーバー
で利用する時です。 最も一般的なシナリオは以下です。
アプリケーションサーバーのデータソースの設定
コネクションのためのデータソースを利用するHibernateの設定
コンテナ管理トランザクションの利用
jBPMトランザクションの無効
jBPMの前にたつステートレスセッションファサードはよいプラクティスです。jBPMトランザクションと
コンテナトランザクションをバインドする最も簡単な方法は、jBPMで利用するHiberanteコンフィグレー
51
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
ションが XAデータソースを利用しているか確認することです。jBPM自身でHibernate sessionを持ち、1
JDBC コネクション、 1トランザクションになります。
T he transaction attribute of the jBPM session facade methods should be 'required'.
jbpm により使用される hibernate.cfg.xm l で指定する最も重要な設定プロパティは
hibernate.connection.datasource です。 これをデータソース JNDI 名 (java:/Jbpm DS など) に設定しま
す。
More information on how to configure JDBC connections in Hibernate, see the Hibernate reference
manual, section 'Hibernate provided JDBC connections'
For more information on how to configure xa datasources in JBoss, see the JBoss application server
guide, section 'Configuring JDBC DataSources'
5.1.4. Hiberante sessionのインジェクション
あるケースでは、既にHibernate sessionを保持していて、jBPMでの永続処理すべてを同一sessionで利用
したいはずです。
その時は、最初にすることは、HibernateコンフィグレーションがjBPMテーブルのマッピングファイルを
知っていることを確認してください。src/config.files/hibernate.cfg.xm l で参照されている
すべてのHibernateマッピングファイルがHiberanateコンフィグレーションで設定されているか確認してく
ださい。
次に、以下の API の例で示されたようにHibernate session をjBPM contextにインジェクションします:
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
jbpmContext.setSession(SessionFactory.getCurrentSession());
// your jBPM operations on jbpmContext
} finally {
jbpmContext.close();
}
それで現在のコンテナで利用されているHibernate sessionがjBPM contextに渡されます。 そのsessionが
contextにインジェクションされた際にはHibernate トランザクションは初期化されません。 デフォルト設
定として利用できます。
渡されたHibernate sessionは jbpmContext.close() メソッドで閉じられません。これは、次のセクション
で説明するプログラムでのインジェクションの全体の考えに沿っています。
5.1.5. プログラムでのリソースインジェクション
Hibernate session factory、Hibernate session、 JDBC connections、 jBPM必須サービスを作成するのに
jBPMの設定は重要な情報を提供します。しかし、すべてのリソースはプログラムで記述しても準備できま
す。 ただjbpmContextにするたけです。インジェクションされたリソースはjBPMコンフィグレーション情
報を作成する前に 必ず取得されます。
基本的な考え方は、jbpmContext にインジェクションする、API利用者がすべての責任を持ちます。 一方
で、jBPMで開いているすべてのアイテムは、jBPMで閉じます。ひとつだけ例外があります。 それは、
Hibernateで作成されたコネクションをフェッチするときです。jbpmContext.getConnection()を呼ぶと
き、 jBPMからのコネクションのクローズをAPIの利用者に任せることになります。
52
第5章 永続性
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
// to inject resources in the jbpmContext
//before they are used, you can use
jbpmContext.setConnection(connection);
// or
jbpmContext.setSession(session);
// or
jbpmContext.setSessionFactory(sessionFactory);
} finally {
jbpmContext.close();
}
5.1.6. 先進的 API利用方法
DbPersistenceServiceは遅延ロードされたHibernateのsessionを維持します。 すべてのデータベースアク
セスは Hibernateのsessionによって行われます。 jBPMによる、すべてのクエリと更新操作は、
GraphSession、SchedulerSession、LoggingSessionなどXxxSessionクラスによって公開されていま
す。これらのセッションクラスは、 Hibernate クエリを参照し、 基礎となる同じHibernate セッションを
使用します。
XxxxSessionクラスはJbpmContext経由でもアクセス可能です。
5.2. 永 続 サ ー ビ ス 設 定
5.2.1. DbPersistenceServiceFactory
DbPersistenceServiceFactory自身は、更に3つの設定プロパティを持っています:
isT ransactionEnabled、sessionFactoryJndiName、dataSourceJndiNameです。 jbpm .cfg.xm lにこれ
らのプロパティを指定するには、 ファクトリ要素中にBeanとしてサービスファクトリを以下のように指
定しなければなりません。
<jbpm-context>
<service name="persistence">
<factory>
<bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
<field name="isTransactionEnabled"><false /></field>
<field name="sessionFactoryJndiName">
<string value="java:/myHibSessFactJndiName" />
</field>
<field name="dataSourceJndiName">
<string value="java:/myDataSourceJndiName" />
</field>
</bean>
</factory>
</service>
...
</jbpm-context>
53
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
重要
ファクトリの設定で短い表記法と長い表記法を混在させないでください (「ファクトリのカスタマ
イズ」 も参照)。 ファクトリがクラス新しいインスタンスの場合は、 ファクトリ属性を使用して
ファクトリクラス名を参照できます。 ただし、 ファクトリのプロパティを設定する必要がある場
合は、 長い表記法を使用し、ファクトリと Bean をネストされた要素として組み合わせる必要があ
ります。
isT ransactionEnabled: デフォルトでは jBPM は、セッションが最初にフェッチされたときに
Hibernate トランザクションを開始し、 jbpmContext が閉じられると、 Hibernate トランザクション
が終了します。 トランザクションは jbpmContext.setRollbackOnly が呼び出されたかどうかに応じて
コミットまたはロールバックされます。 isRollbackOnly プロパティは T xService で管理されます。 ト
ランザクションを無効にし、 jBPM が Hibernate でトランザクションを管理しないようにするには、
上記の例で isT ransactionEnabled プロパティを false に設定します。 このプロパティは jbpmContext
の動作のみを制御し、 API を使用して DbPersistenceService.beginT ransaction() を直接呼び出すこと
ができます。 この場合、 isT ransactionEnabled 設定は無視されます。 トランザクションの詳細につ
いては、 「Hibernateトランザクション」 を参照してください。
sessionFactoryJndiName : デフォルトでは、nullで、JNDIからsession factoryを取得しないように
なっています。 session factoryを必要とする場合、Hibernate sessionを作成するために、 session
factoryは、提供されたJNDI名を利用してJNDIから取得されます。
dataSourceJndiName: デフォルトでは、nullで、JDBCコネクションの作成/取得はhibernateに委譲
します。 データソースを指定すると、jBPMはJDBCコネクションをデータソースから取得して、 新し
いsessionを開いている間にHibernateにコネクションを渡します。
5.2.2. Hibernate sessionファクトリ
By default, the DbPersistenceServiceFactory will use the resource hibernate.cfg.xml in the root of the
classpath to create the Hibernate session factory. Note that the Hibernate configuration file resource is
mapped in the property 'jbpm.hibernate.cfg.xml' and can be customized in the jbpm.cfg.xml. T his is the
default configuration:
<jbpm-configuration>
<!-- configuration resource files pointing to default
configuration files in jbpm-{version}.jar -->
<string name='resource.hibernate.cfg.xml'
value='hibernate.cfg.xml' />
<!-- <string name='resource.hibernate.properties'
value='hibernate.properties' /> -->
</jbpm-configuration>
resource.hibernate.properties のプロパティが指定されたとき、 リソースファイルにあるそのプロパ
ティは、 hibernate.cfg.xmlにあるプロパティすべてをオーバーライド します。 DBに対する
hibernate.cfg.xmlの更新を行うかわりに、 jbpmの更新を便利に制御するためにhibernate.propertiesが利用
可能です。 この場合、hibernate.cfg.xmlは、変更に対して再適応処理を行わなくても、コピーされます。
5.2.3. c3poコネクションプール設定
Hibernateのドキュメントhttp://www.hibernate.org/214.htmlを参照してください。
5.2.4. ehcacheキャッシュプロバイダ設定
jBPMでJBossCacheを設定したい場合は、 jBPM設定に関するwikiページを見てください。
For more information about configuring a cache provider in Hibernate, take a look at the Hibernate
54
第5章 永続性
documentation, section 'Second level cache'
jBPM で提供している hibernate.cfg.xm l は次の行を含んでいます:
<property name="hibernate.cache.provider_class">
org.hibernate.cache.HashtableCacheProvider
</property>
これでクラスパスの心配することもなく、人を可能なかぎり速く動くようにします。 Hibernate は
HashtableCacheProvider を実稼働環境では使用しないようにする 警告を含んでいることに注意してくだ
さい。
HashtableCacheProvider の代わりに ehcacheを利用したい場合、単純にその行を削除
し、ehcache.jar にクラスパスをとおすだけです。 自分の環境にあった正確な ehcache ライブラリの
バージョンを確認する必要があるかもしれないということに注意してください。以前存在した JBoss バー
ジョンと perticular ehcache バージョンの間の前の非互換性が、デフォルトを HashtableCacheProvider
に変えた理由でした。
5.3. Hibernateト ラ ン ザ ク シ ョ ン
By default, jBPM will delegate transactions to Hibernate and use the "session per transaction" pattern.
jBPM will begin a Hibernate transaction when a Hibernate session is opened. T his will happen the first
time when a persistent operation is invoked on the jbpmContext. T he transaction will be committed right
before the Hibernate session is closed. T hat will happen inside the jbpm Context.close().
トランザクションのロールバックを行うには、 jbpm Context.setRollbackOnly() を利用してくだ
さい。 その場合、 jbpm Context.close() 内でセッションがクローズされる直前にロールバックされ
ます。
jBPM が Hibernate API でトランザクションメソッドを呼び出さないようにするには、 上記の
「DbPersistenceServiceFactory」 で説明したように isT ransactionEnabled プロパティを false に設定し
ます。
5.4. JTAト ラ ン ザ ク シ ョ ン
もっとも一般的なトランザクション管理をするシナリオは JBoss のようなアプリケーションサーバーで
jBPM を 動作させる場合です。トランザクションを JT A にバインドするもっとも一般的な方法は次のよう
になります:
<jbpm-context>
<service name="persistence">
<factory>
<bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
<field name="isTransactionEnabled"><false /></field>
<field name="isCurrentSessionEnabled"><true /></field>
<field name="sessionFactoryJndiName">
<string value="java:/myHibSessFactJndiName" />
</field>
</bean>
</factory>
</service>
</jbpm-context>
T hen you should specify in your Hibernate session factory to use a datasource and bind Hibernate to
the transaction manager. Make sure that you bind the datasource to an XA datasource in case you are
55
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
using more than one resource. For more information about binding Hibernate to your transaction
manager, please, refer to paragraph 'T ransaction strategy configuration' in the Hibernate documentation.
<hibernate-configuration>
<session-factory>
<!-- hibernate dialect -->
<property name="hibernate.dialect">
org.hibernate.dialect.HSQLDialect
</property>
<!-- DataSource properties (begin) -->
<property name="hibernate.connection.datasource">
java:/JbpmDS
</property>
<!-- JTA transaction properties (begin) -->
<property name="hibernate.transaction.factory_class">
org.hibernate.transaction.JTATransactionFactory
</property>
<property name="hibernate.transaction.manager_lookup_class">
org.hibernate.transaction.JBossTransactionManagerLookup
</property>
<property name="jta.UserTransaction">
java:comp/UserTransaction
</property>
</session-factory>
</hibernate-configuration>
最後にHibernateの設定でXAデータソースを利用するように設定していることを確認してください。
T hese configurations allow for the enterprise beans to use CMT and still allow the web console to use
BMT . T hat is why the property 'jta.UserT ransaction' is also specified.
5.5. ク エ リ の カ ス タ マ イ ズ
全てのjBPMが利用するHQLクエリはひとつの設定ファイルに集中しています。 そのリソースファイル
は、このようなhibernate.cfg.xmlで参照されています。
<hibernate-configuration>
<!-- hql queries and type defs -->
<mapping resource="org/jbpm/db/hibernate.queries.hbm.xml" />
</hibernate-configuration>
T o customize one or more of those queries, take a copy of the original file and put your customized
version somewhere on the classpath. T hen update the reference
'org/jbpm/db/hibernate.queries.hbm.xml' in the hibernate.cfg.xml to point to your customized version.
5.6. デ ー タ ベ ー ス 互 換 性
jBPMはHibernateでサポートしているデータベースであれば、 どのデータベースでも動作します。
T he example configuration files in jBPM (src/config.files) specify the use of the hypersonic inmemory database. T hat database is ideal during development and for testing. T he hypersonic inmemory database keeps all its data in memory and doesn't store it on disk.
56
第5章 永続性
5.6.1. JDBC接続の分離レベル
JDBC接続に対して設定したデータベース分離レベルが少なくともREAD_COMMIT T EDであることを確認
してください。
ほとんどすべての機能はREAD_UNCOMMIT T ED (分離レベル0およびHSQLDBによってのみサポート)でも
問題なく動作しますが、ジョブエクセキュータで競合が発生し、複数のトークンを同期することがありま
す。
5.6.2. jBPM DBの変更
次の内容は、jBPMを異なるデータベースに利用する場合に、行うことを示しています。
JDBCドライバにクラスパスを通します。
jBPMで利用するHibernate設定を変更します。
新しいデータベースのスキーマを作成します。
5.6.3. jBPMデータベーススキーマ
jbpm.db サブプロジェクトは、選択したデータベースで始めるのに役立つドライバ、ガイド、スクリプト
を含んでいます。 より詳細な情報は、jbpm.db プロジェクトのルートにある readm e.htm l を参照して
ください。
jBPMがすべてのデータベース用DDLを生成することができるとはいえ、 そのスキーマは必ずしも最適化
されたものではありません。 カラム属性、インデックスなど最適化するために、 DBAに生成されたDDL
をレビューしてもらったほうがいいかもしれません。
In development you might be interested in the following Hibernate configuration: If you set Hibernate
configuration property 'hibernate.hbm2ddl.auto' to 'create-drop' (e.g. in the hibernate.cfg.xml), the schema
will be automatically created in the database the first time it is used in an application. When the
application closes down, the schema will be dropped.
スキーマ生成処理はプログラム上、 jbpm Configuration.createSchem a() と
jbpm Configuration.dropSchem a() で呼び出すことができます。
5.7. Hibernate ク ラ ス の 組 み 合 わ せ
In your project, you might use Hibernate for your persistence. Combining your persistent classes with
the jBPM persistent classes is optional. T here are two major benefits when combining your Hibernate
persistence with jBPM's Hibernate persistence:
First, session, connection and transaction management become easier. By combining jBPM and your
persistence into one Hibernate session factory, there is one Hibernate session, one JDBC connection
that handles both yours and jBPM's persistence. So automatically the jBPM updates are in the same
transaction as the updates to your own domain model. T his can eliminate the need for using a
transaction manager.
2つめに、これ以上の手間をかけることなく、使用する Hibernate 永続化オブジェクトを プロセス変数へ
入れることができるようになります。
永続クラスを jBPM 永続クラスと統合する最も簡単な方法は、 1 つの中央 hibernate.cfg.xml を作成する
ことです。 jBPM hibernate.cfg.xm l を基に独自の Hibernate マッピングファイルへの参照を追加し
ます。
57
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
5.8. jBPM Hibernate マ ッ ピ ン グ フ ァ イ ル の カ ス タ マ イ ズ
Hibernateマッピングファイルをカスタマイズするには、 以下の手順で進めます。
1. コピーしたい jBPM Hibernate マッピングファイルをソース (src/jbpm -jpdl-sources.jar) か
らコピーします。
2. クラスパスの好きな場所にコピーを置きます。 ただし、 以前とまったく同じ場所にならないように
してください。
3. hibernate.cfg.xm l設定ファイルのカスタマイズマッピングファイルへの参照を変更します。
5.9. 2 次 レ ベ ル キ ャ ッ シ ュ
jBPM uses Hibernate's second level cache for keeping the process definitions in memory after loading
them once. T he process definition classes and collections are configured in the jBPM Hibernate mapping
files with the cache element like this:
<cache usage="nonstrict-read-write"/>
プロセス定義は変更しないため、 2 次キャッシュに保持することができます。 「デプロイ済プロセス定
義の変更」 も参照してください。
T he second level cache is an important aspect of the JBoss jBPM implementation. If it weren't for this
cache, JBoss jBPM could have a serious drawback in comparison to the other techniques to implement a
BPM engine.
デフォルトのキャッシュ方針では、 nonstrict-read-write に設定されます。 プロセスの実行中にプ
ロセス定義は静的です。 この結果、 プロセスの実行中に最大のキャッシュが取得されます。 理論的には
キャッシュ方針 read-only はランタイム実行に適しています。 この場合、 操作は読み取り専用でない
ため、 新しいプロセス定義をデプロイすることができません。
[1] 4章 設定.
58
第6章 Java EE アプリケーションサーバー機能
第 6章 Java EE アプリケーションサーバー機能
この章では、 Java EE インフラストラクチャを活用するために jBPM によって提供される機能について説
明します。
6.1. エ ン タ ー プ ラ イ ズ Bean
Com m andServiceBean is a stateless session bean that executes jBPM commands by calling it's
execute method within a separate jBPM context. T he environment entries and resources available for
customization are summarized in the table below.
表 6.1 コマンドサービス Bean 環境
名前
種類
説明
Jbpm CfgResource
環境エントリ
jBPM 設定を読み取るクラスパスリソース。
省略可能であり、 デフォルトで
jbpm .cfg.xm l に設定されます。
ejb/T im erEntityBean
EJB 参照
スケジューラサービスを実装するローカルエ
ンティティ Bean へのリンク。 タイマーを含
むプロセスに必要です。
jdbc/Jbpm DataSource
リソースマネー
ジャ参照
JDBC 接続を jBPM 永続サービスに提供する
データソースの論理名。 Hibernate 設定ファ
イルの
hibernate.connection.datasource
プロパティに一致する必要があります。
jm s/Jbpm ConnectionFactory
リソースマネー
ジャ参照
JMS 接続を jBPM メッセージサービスに提供
するファクトリの論理名。 非同期続行を含む
プロセスに必要です。
jm s/JobQueue
メッセージ送信
先参照
jBPM メッセージサービスは、ここで参照さ
れるキューにジョブにメッセージを送信しま
す。 これが、 ジョブリスナー Bean がメッ
セージを受信したのと同じキューになるよう
に、 m essage-destination-link が一般
的かつ論理的な送信先 JobQueue を参照しま
す。
jm s/Com m andQueue
メッセージ送信
先参照
コマンドリスナー Bean は、 ここで参照され
たキューからメッセージを受信します。 これ
が、 コマンドメッセージを送信できるのと同
じキューになるように、 m essagedestination-link elem ent は一般的か
つ論理的な送信先 Com m andQueue を参照し
ます。
Com m andListenerBean はコマンドメッセージを Com m andQueue でリッスンするメッセージ駆動
Bean です。 この Bean はコマンド実行を Com m andServiceBean に委譲します。
メッセージ本体は org.jbpm .Com m and インタフェースを実装する Java オブジェクトである必要があ
ります。 メッセージプロパティ (存在する場合) は無視されます。 メッセージが予期される書式に一致し
ない場合、 メッセージは DeadLetterQueue に転送されます。 メッセージに対してはその他の処理は
行われません。 送信先参照が存在しない場合、 メッセージは拒否されます。
59
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
受信されたメッセージがreplyT o 返信先を指定している場合、 コマンド実行の結果はオブジェクトに
ラップされ、 その返信先に送信されます。 コマンド接続ファクトリ環境変数は、 JMS 接続を提供するリ
ソースマネージャを指定します。
JobListenerBean は、 非同期続行をサポートするために Jbpm JobQueue 上でジョブメッセージを
リッスンするメッセージ駆動 Bean です。
メッセージは、 データベースの待機 Job を参照する、 long データ型の jobId というプロパティを持
つ必要があります。 メッセージ本体 (存在する場合) は無視されます。
この Bean は Com m andListenerBean を拡張し、 その環境エントリとカスタム化に利用可能なリソー
ス参照を継承します。
表 6.2 コマンド /ジョブリスナー Bean 環境
名前
種類
説明
ejb/LocalCom m andServiceBean
EJB 参照
別の jBPM コンテキストでコマンドを実
行する論理的なセッション Bean へのリ
ンク。
jm s/Jbpm ConnectionFactory
リソースマネー
ジャ参照
結果メッセージを生成するために JMS
接続を提供するファクトリの論理名。 返
信先を指定するコマンドメッセージに必
要です。
jm s/DeadLetterQueue
メッセージ送信
先参照
コマンドを含まないメッセージは、 ここ
で参照されるキューに送信されます。 省
略可能であり、 使用しない場合、 この
ようなメッセージは拒否され、 コンテが
再配信することがあります。
T im erEntityBean は、 EJB タイマーサービスと対話し、 jBPM タイマーをスケジュールします。 有効
期限が切れると、 タイマーの実行は実際にはコマンドサービス Bean に委譲されます。
タイマーエンティティ Bean は、タイマーデータを読み取るために jBPM データソースにアクセスする必
要があります。 EJB デプロイメント記述子では、 エンティティ Bean をデータベースにマップする方法
を定義できません。 JBoss AS では、 jbosscm p-jdbc.xm l 記述子を使用してデータソース JNDI 名と
リレーショナルマッピングデータ (テーブルや列名など) を定義できます。 リソースマネージャ参照
(java:com p/env/jdbc/Jbpm DataSource) と異なり、 JBoss CMP 記述子はグローバル JNDI 名
(java:Jbpm DS) を使用します。
jBPM の以前のバージョンでは、 EJB タイマーサービスと対話するために T im erServiceBean という
名前のステートレスセッション Bean が使用されていました。 このセッション方式は、 キャンセル方方
に回避できないボトルネックが存在するため廃止するひつようがありました。 セッション Bean は ID を
持たないため、 タイマーサービスによってすべてのタイマーが強制的に反復処理あれ、 キャンセルする
必要があるタイマーを見つけます。 Bean には依然として後方互換性があります。 Bean は
T im erEntityBean と同じ環境で動作するため、 移行は簡単です。
表 6.3 タイマーエンティティ /サービス Bean 環境
名前
種類
説明
ejb/LocalCom m andServiceBean
EJB 参照
別の jBPM コンテキストでタイマーを実行
するローカルのセッション Bean へのリン
ク。
60
第6章 Java EE アプリケーションサーバー機能
6.2. jBPM エ ン タ ー プ ラ イ ズ 設 定
jbpm .cfg.xm l には以下の設定項目が含まれます。
<jbpm-context>
<service name="persistence"
factory="org.jbpm.persistence.jta.JtaDbPersistenceServiceFactory" />
<service name="message"
factory="org.jbpm.msg.jms.JmsMessageServiceFactory" />
<service name="scheduler"
factory="org.jbpm.scheduler.ejbtimer.EntitySchedulerServiceFactory" />
</jbpm-context>
JtaDbPersistenceServiceFactory を使用すると、 jBPM は JT A トランザクションに参加できま
す。 既存のトランザクションが処理中の場合、 JT A 永続サービスはそのトランザクションを引き続き使
用しようとします。 その他の場合は、 新しいトランザクションが開始されます。 BPM エンタープライズ
Bean は、 トランザクション管理をコンテナに委譲するよう設定されます。 ただし、 トランザクション
がアクティブな環境 (たとえば、 Web アプリケーション) で JbpmContext を作成する場合、
JbpmContext は自動的に起動されます。 JT A 永続サービスファクトリは以下で説明された設定可能な
フィールドを持ちます。
isCurrentSessionEnabled
When set to true, jBPM will use the "current" Hibernate session associated with the ongoing
JT A transaction. T his is the default setting. See the Hibernate guide, section 2.5 Contextual
sessions for a description of the behavior. You can take advantage of the contextual session
mechanism to use the same session used by jBPM in other parts of your application through a
call to SessionFactory.getCurrentSession(). On the other hand, you might want to
supply your own Hibernate session to jBPM. T o do so, set isCurrentSessionEnabled to
false and inject the session via the Jbpm Context.setSession(session) method. T his
will also ensure that jBPM uses the same Hibernate session as other parts of your application.
Note, the Hibernate session can be injected into a stateless session bean via a persistence
context, for example.
isT ransactionEnabled
When set to true jBPM will begin a transaction through Hibernate's transaction API (section
11.2. Database transaction demarcation of the Hibernate manual shows the API) upon
Jbpm Configuration.createJbpm Context(), commit the transaction and close the
Hibernate session upon Jbpm Context.close(). T his is NOT the desired behaviour when
jBPM is deployed as an ear, hence isT ransactionEnabled is set to false by default.
Jm sMessageServiceFactory は JMS によって公開された、信頼できる通信インフラストラクチャを
活用して非同期続行メッセージを JobListenerBean に配信します。 JMS メッセージをサービスファク
トリは以下の設定フィールドを公開します。
connectionFactoryJndiName
JNDI 初期コンテキスト内の JMS 接続ファクトリの名前。 デフォルトで
java:com p/env/jm s/Jbpm ConnectionFactory に設定されます。
destinationJndiName
61
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
ジョブメッセージが送信される JMS 送信先の名前。 JobListenerBean が受信するメッセージ
の送信元に一致する必要があります。 デフォルトで java:com p/env/jm s/JobQueue に設定
されます。
isCommitEnabled
T his specifies whether jBPM should commit the JMS session upon Jbpm Context.close().
Messages produced by the JMS message service are never meant to be received before the
current transaction commits; hence the JMS sessions created by the service are always
transacted. T he default value -false- is appropriate when the connection factory in use is XA
capable, as the JMS session's produced messages will be controlled by the overall JT A
transaction. T his field should be set to true if the JMS connection factory is not XA capable so
that jBPM commits the JMS session's local transaction explicitly.
EntitySchedulerServiceFactory は、 ビジネスプロセスタイマーをスケジュールするために、
EJB コンテナによって提供されたタイムイベントのトランザクション通知サービス上に構築されます。
EJB スケジューラサービスファクトリは以下で説明された設定可能なフィールドを持ちます。
timerEntityHomeJndiName
T he name of the T im erEntityBean's local home interface in the JNDI initial context. Defaults
to java:com p/env/ejb/T im erEntityBean.
6.3. Hibernate エ ン タ ー プ ラ イ ズ 設 定
hibernate.cfg.xm l には、他のデータベースまたはアプリケーションサーバーをサポートするために
変更できる以下の設定項目が含まれます。
62
第6章 Java EE アプリケーションサーバー機能
<!-- sql dialect -->
<property name="hibernate.dialect">
org.hibernate.dialect.HSQLDialect
</property>
<property name="hibernate.cache.provider_class">
org.hibernate.cache.HashtableCacheProvider
</property>
<!-- DataSource properties (begin) -->
<property name="hibernate.connection.datasource">
java:comp/env/jdbc/JbpmDataSource
</property>
<!-- DataSource properties (end) -->
<!-- JTA transaction properties (begin) -->
<property name="hibernate.transaction.factory_class">
org.hibernate.transaction.JTATransactionFactory
</property>
<property name="hibernate.transaction.manager_lookup_class">
org.hibernate.transaction.JBossTransactionManagerLookup
</property>
<!-- JTA transaction properties (end) -->
<!-- CMT transaction properties (begin) ===
<property name="hibernate.transaction.factory_class">
org.hibernate.transaction.CMTTransactionFactory
</property>
<property name="hibernate.transaction.manager_lookup_class">
org.hibernate.transaction.JBossTransactionManagerLookup
</property>
==== CMT transaction properties (end) -->
hibernate.dialect は、 使用しているデータベース管理システムに対応するものに置き換えることが
できます。 利用可能なデータベースダイアレクトのリストについては、 Hibernate リファレンスガイドの
セクション 3.4.1 SQL dialects を参照してください。
HashtableCacheProvider は、 サポートされる他のキャッシュプロバイダに置き換えることができ
ます。 サポートされるキャッシュプロバイダのリストについては、Hibernate マニュアルのセクション
19.2 T he second level cache を参照してください。
JBossT ransactionManagerLookup は、 JBoss 以外のアプリケーションサーバーに適切な方針に置
き換えることができます。 各アプリケーションサーバーに対応するルックアップクラスを見つけるには、
セクション 3.8.1 T ransaction strategy configuration を参照してください。
hibernate.connection.datasource で使用される JNDI 名は実際にはアプリケーションサーバー間
で移植可能なリソースマネージャ参照です。 この参照はデプロイ時に対象アプリケーションサーバーの実
際のデータソースにバインドされます。 含まれた jboss.xm l 記述子では、 参照は java:Jbpm DS にバ
インドされます。
出荷された状態で、 jBPM は JT AT ransactionFactory を使用するよう設定されています。 既存のト
ランザクションが実行中の場合は、 JT A トランザクションが JT AT ransactionFactory を使用しま
す。 その他の場合は、 新しいトランザクションが生成されます。 jBPM エンタープライズ Bean はトラン
ザクション管理をコンテナに委譲するよう設定されます。 ただし、 トランザクションがアクティブでな
いコンテキスト (たとえば、 Web アプリケーション) で jBPM API を使用する場合は、 自動的に起動しま
す。
63
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
独自の EJB がコンテナ管理トランザクションを使用し、 予期しないトランザクションの生成を回避した
い場合は、 CMT T ransactionFactory に切り替えることができます。 この設定では、 Hibernate は常
に既存のトランザクションを検索し、 見つからない場合は問題を報告します。
6.4. ク ラ イ ア ン ト コ ン ポ ー ネ ン ト
エンタープライズサービスを使用する jBPM API に対して直接的に作成されたクライアントコンポーネン
トでは、 デプロイメント記述子で適切な環境参照が設定されている必要があります。 以下の記述子は、
クライアントセッション Bean の典型と見なすことができます。
<session>
<ejb-name>MyClientBean</ejb-name>
<home>org.example.RemoteClientHome</home>
<remote>org.example.RemoteClient</remote>
<local-home>org.example.LocalClientHome</local-home>
<local>org.example.LocalClient</local>
<ejb-class>org.example.ClientBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<ejb-local-ref>
<ejb-ref-name>ejb/TimerEntityBean</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<local-home>org.jbpm.ejb.LocalTimerEntityHome</local-home>
<local>org.jbpm.ejb.LocalTimerEntity</local>
</ejb-local-ref>
<resource-ref>
<res-ref-name>jdbc/JbpmDataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<resource-ref>
<res-ref-name>jms/JbpmConnectionFactory</res-ref-name>
<res-type>javax.jms.ConnnectionFactory</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<message-destination-ref>
<message-destination-ref-name>
jms/JobQueue
</message-destination-ref-name>
<message-destination-type>javax.jms.Queue</message-destination-type>
<message-destination-usage>Produces</message-destination-usage>
</message-destination-ref>
</session>
対象アプリケーションサーバーが JBoss である場合、 以下のように上記の環境参照を対象稼働環境のリ
ソースにバインドできます。 JNDI 名が、 jBPM エンタープライズ Bean によって使用された値に一致す
ることに注意してください。
64
第6章 Java EE アプリケーションサーバー機能
<session>
<ejb-name>MyClientBean</ejb-name>
<jndi-name>ejb/MyClientBean</jndi-name>
<local-jndi-name>java:ejb/MyClientBean</local-jndi-name>
<ejb-local-ref>
<ejb-ref-name>ejb/TimerEntityBean</ejb-ref-name>
<local-jndi-name>java:ejb/TimerEntityBean</local-jndi-name>
</ejb-local-ref>
<resource-ref>
<res-ref-name>jdbc/JbpmDataSource</res-ref-name>
<jndi-name>java:JbpmDS</jndi-name>
</resource-ref>
<resource-ref>
<res-ref-name>jms/JbpmConnectionFactory</res-ref-name>
<jndi-name>java:JmsXA</jndi-name>
</resource-ref>
<message-destination-ref>
<message-destination-ref-name>
jms/JobQueue
</message-destination-ref-name>
<jndi-name>queue/JbpmJobQueue</jndi-name>
</message-destination-ref>
</session>
クライアントコンポーネントがエンタープライズ Bean ではなく Web アプリケーションである場合は、
デプロイメント記述子は以下のようになります。
65
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
<web-app>
<servlet>
<servlet-name>MyClientServlet</servlet-name>
<servlet-class>org.example.ClientServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyClientServlet</servlet-name>
<url-pattern>/client/servlet</url-pattern>
</servlet-mapping>
<ejb-local-ref>
<ejb-ref-name>ejb/TimerEntityBean</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<local-home>org.jbpm.ejb.LocalTimerEntityHome</local-home>
<local>org.jbpm.ejb.LocalTimerEntity</local>
<ejb-link>TimerEntityBean</ejb-link>
</ejb-local-ref>
<resource-ref>
<res-ref-name>jdbc/JbpmDataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<resource-ref>
<res-ref-name>jms/JbpmConnectionFactory</res-ref-name>
<res-type>javax.jms.ConnectionFactory</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<message-destination-ref>
<message-destination-ref-name>
jms/JobQueue
</message-destination-ref-name>
<message-destination-type>javax.jms.Queue</message-destination-type>
<message-destination-usage>Produces</message-destination-usage>
<message-destination-link>JobQueue</message-destination-link>
</message-destination-ref>
</web-app>
対象アプリケーションサーバーが JBoss の場合、 上記の環境参照は、以下のように対象稼働環境のリ
ソースにバインドできます。 Boss
66
第6章 Java EE アプリケーションサーバー機能
<jboss-web>
<ejb-local-ref>
<ejb-ref-name>ejb/TimerEntityBean</ejb-ref-name>
<local-jndi-name>java:ejb/TimerEntityBean</local-jndi-name>
</ejb-local-ref>
<resource-ref>
<res-ref-name>jdbc/JbpmDataSource</res-ref-name>
<jndi-name>java:JbpmDS</jndi-name>
</resource-ref>
<resource-ref>
<res-ref-name>jms/JbpmConnectionFactory</res-ref-name>
<jndi-name>java:JmsXA</jndi-name>
</resource-ref>
<message-destination-ref>
<message-destination-ref-name>
jms/JobQueue
</message-destination-ref-name>
<jndi-name>queue/JbpmJobQueue</jndi-name>
</message-destination-ref>
</jboss-web>
67
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
第 7章 プロセスのモデリング
7.1. 概 要
プロセス定義は、ビジネスプロセスの形式仕様を表したもので、 有向グラフに基づいています。 そのグ
ラフは、ノードと遷移で構成されています。グラフ内の全てのノードは、 特定のタイプを持っています。
ノードのタイプはランタイムの振る舞いを定義します。 プロセス定義は、必ず 1つの開始状態を持って
います。
トークンは、ひとつの実行パスです。 トークンは、グラフ中でノードへのポインタを維持する実行時の概
念です。
プロセスインスタンスとは、ひとつのプロセス定義の実行です。 プロセスインスタンスが作成される時、
実行のメインパスのトークンも作成されます。 このトークンは、プロセスインスタンスのルートトークン
と呼ばれ、 プロセス定義の開始状態に位置しています。
シグナルがトークンに、グラフ実行の継続を指示します。 名前のないシグナルを受け取った場合、 トー
クンは、デフォルト退場遷移で、その時に位置していたノードを退場します。 遷移名がシグナル上で、指
定されている場合、 指定されている遷移で、その時のノードを退場します。 プロセスインスタンスに与
えられたシグナルは、ルートトークンに委譲されます。
トークンがノードに入場後、そのノードは実行されます。 ノード自身はグラフ実行の継続の責務がありま
す。トークンをノードから退場させることで、グラフ実行の継続が行われます。 各ノードタイプは、グラ
フ実行のための異なる振る舞いを実装することもできます。 実行を伝播しないノードは、状態として振る
舞います。
Action は、実行プロセスの中で、 イベント上で実行される Java コードの一部です。 グラフは、ソフト
ウェア要件を伝達する重要な道具です。 しかし、 グラフは、作成されるソフトウェアの単なるビュー(投
影)にすぎません。 それは、たくさんの技術的な詳細を隠蔽します。 Action は、グラフ表現とは別に、技
術的な詳細を追加するメカニズムです。 グラフがデプロイされれば、Action を付け足すことが可能です。
主な、イベントタイプは、ノード入場時、ノード退場時、遷移時です。
7.2. プ ロ セ ス グ ラ フ
プロセス定義の基本は、ノードと遷移で作成されるグラフです。 その情報
は、processdefinition.xm lと呼ばれるxmlファイルで表現されます。 各ノードは、state, decision,
fork, join,...というタイプを持ちます。 各ノードは、退場ノードのセットを持っています。 退場する遷移に
は、各ノードを明確にするためにも名前がつけられます。 例えば、次図は、jBAYオークションプロセスの
プロセスグラフを示しています。
68
第7章 プロセスのモデリング
図 7.1 オークションプロセスグラフ
下記は、xmlで表現したjBAYオークションプロセスのプロセスグラフです。
69
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
<process-definition>
<start-state>
<transition to="auction" />
</start-state>
<state name="auction">
<transition name="auction ends" to="salefork" />
<transition name="cancel" to="end" />
</state>
<fork name="salefork">
<transition name="shipping" to="send item" />
<transition name="billing" to="receive money" />
</fork>
<state name="send item">
<transition to="receive item" />
</state>
<state name="receive item">
<transition to="salejoin" />
</state>
<state name="receive money">
<transition to="send money" />
</state>
<state name="send money">
<transition to="salejoin" />
</state>
<join name="salejoin">
<transition to="end" />
</join>
<end-state name="end" />
</process-definition>
7.3. ノ ー ド
プロセスグラフは、ノードと遷移から構成されます。 グラフと実行モデルに関する詳細については、 3
章グラフ指向プログラミング を参照してください。
各ノードは、特定タイプを持っています。 そのノードタイプは、ランタイムに、ノードへ実行(トーク
ン)が入場したときに、何をするかを決定します。 jBPM には、使用可能な 事前に用意されたノードタイ
プのセットがあります。 代わりに、特別なノード動作実装の ためにカスタムコードを書くこともできま
す。
7.3.1. ノード責務
各ノードには、2つの主な責務があります。 一つ目に、純粋なjavaコードを実行できるということ、 基本
的には、そのjavaコードは、そのノードと関係したものです。 例えば、いくつかのタスクインスタンスの
作成、通知、データベースの更新など、 2つ目に、ノードは、実行を伝播する責務があります。 基本的
には、各ノードは実行の伝播を行うために次の いくつかのオプションがあります:
1. not propagate the execution. このケースではノードが、 待機状態として振る舞います。
70
第7章 プロセスのモデリング
1. not propagate the execution. このケースではノードが、 待機状態として振る舞います。
2. propagate the execution over one of the leaving transitions of the node. これは、既に
ノードに入場したトークンが、 API 呼び出し executionContext.leaveNode(String) により、退場遷移
のひとつを通過したことを意味します。 このノードは、カスタムプログラミングロジックを実行可能
な自動ノードとして動作し、 待機することなく自動的にプロセス実行を継続します。
3. create new paths of execution. A node can decide to create new tokens. Each new token
represents a new path of execution and each new token can be launched over the node's leaving
transitions. A good example of this kind of behavior is the fork node.
4 . end paths of execution. ノードは、実行パスの終了を決定できます。 それは、トークンが終了
して、その実行パスも終了することを意味します。
5. more general, a node can modify the whole runtime structure of the process instance.
ランタイムの構造は、トークンのツリーを含んだプロセスインスタンスです。 各トークンは、実行パ
スを表しています。 ノードは、トークンの作成と終了、トークンをグラフのノードに置いたり、遷移
の際に、 トークンを動かすことができます。
すべての ワークフローおよび BPM エンジンと同様に jBPM には、 特別に準備された設定と動作を持つ事
前に実装されたノードタイプのセットが含まれます。 ただし、jBPM およびグラフ指向プログラミングの
基礎 [2] に関するユニークな点は、 開発者のモデルを開くことです。 開発者は、 独自のノードの動作を非
常に簡単に記述し、 プロセスで使用できます。
そこは、伝統的なワークフローと BPM システムがとても閉鎖的な世界です。 それらは、通常、ノードタ
イプの固定されたセット(プロセス言語と呼ばれてます)を提供します。 それらのプロセス言語は、閉鎖的
で、実行モデルは、ランタイム環境に隠蔽されています。 ワークフローパターン の調査結果では、 どの
プロセス言語も十分な実力ではないことを示しています。 jBPM は、シンプルなモデルとすることに決
め、開発者に独自のノードタイプの 記述を可能にしました。 JPDL プロセス言語の方向性がオープンに落
ち着いたところです。
次に、JPDLの重要なノードタイプを説明します。
7.3.2. ノードタイプ - タスクノード (task-node)
タスクノードは、一人以上の人によって遂行されるタスクを表現します。 実行がタスクノードに入場する
時に、 タスクインスタンスがワークフロー関係者のタスクリスト中に作成されます。 その後、ノード
は、待機状態として振る舞います。 ユーザが、そのタスクを遂行した時、 タスク終了することが実行の
再開を引き起こします。 言い換えれば、トークンで呼ばれる新しいシグナルにつながります。
7.3.3. ノードタイプ - 状態 (state)
状態は、最低限機能を備えた待機状態です。 タスクノードとの違いは、 タスクリスト中ではどのような
タスクインスタンスも作成されないことです。 これは、プロセスが外部システムを待つ場合に役立ちま
す。 例えば、ノードが入場するとき(ノード入場イベント時の Action 経由)、 メッセージは、外部システ
ムに送られるかもしれません。 その後で、プロセスは、待機状態に入ります。 外部システムがレスポン
スメッセージを送信するとき、を引き起こせます。それは、実行プロセスの再開をを引き起こす
token.signal() へと結果します。
7.3.4. ノードタイプ - 決定 (decision)
実際には、 誰が決定を行うかによって決定をモデル化する 2 つの方法があります。
1. 決定はプロセスにより行われ、プロセス定義に指定されます。
2. 外部エンティティが決定の結果を提供します。
プロセスが決定を行う場合、決定ノードが使用されます。基本的に決定基準を指定するには2つの方法が
あります。最も簡単な方法は、遷移でcondition要素を追加することです。条件はEL式またはブール変数を
返すbeanshellスクリプトです。
71
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
ランタイム時に決定ノードは条件を指定した退場遷移上で最初にループします。これにより、xml で指定
された順序でこれらの遷移が評価されます。条件が true に解決された最初の 遷移が取得されます。条件
を持つすべての遷移が false に解決されると、デフォルトの遷移 (XML で最初の遷移) が取得されます。
Another approach is to use an expression that returns the name of the transition to take. With the
'expression' attribute, you can specify an expression on the decision that has to resolve to one of the
leaving transitions of the decision node.
Next approach is the 'handler' element on the decision, that element can be used to specify an
implementation of the DecisionHandler interface can be specified on the decision node. T hen the
decision is calculated in a Java class and the selected leaving transition is returned by the decidemethod of the DecisionHandler implementation.
その決定が、外部パーティ(プロセス定義の一部でない、という意味)によって導かれるものであれば、
複数の退場遷移や待ち状態を利用するべきです。 退場遷移は、待機状態が終了後、 実行処理を再開させ
る外部システムに用意できます。 例えば、T oken.signal(String transitionNam e) と
T askInstance.end(String transitionNam e)です。
7.3.5. ノードタイプ - フォーク (fork)
フォークは、1つの実行パスを複数の並列実行パスに分岐します。フォークのデフォルトの 振る舞いは、
フォークから退場する各遷移の子トークンを作成すること、フォークに入場してきたトークンとの親子関
係を作成することです。
7.3.6. ノードタイプ - ジョイン (join)
デフォルトのジョインでは、 ジョインに入場するすべてのトークンは、同じ親の子トークンであると見な
しています。 この状況は、上記で説明したような、フォークを利用する時や、 フォークで作成されたす
べてのトークンが同じジョインに入場したときに作られます。 ジョインは、ジョインに入場したすべての
トークンを終了します。 次に、ジョインは、ジョインに入場したトークンの親子関係を調べます。 すべ
ての兄弟トークンが入場した場合、 親トークン(唯一)は、退場遷移のときに伝播されます。 親トークン
は、退場遷移を通過時に伝播されます。 まだ、兄弟トークンがアクティブな場合、 ジョインは、待機状
態として振る舞います。
7.3.7. ノードタイプ - ノード (node)
タイプノードは、 独自のコードをノードで記述する場合に対応します。 ノードタイプノードは 1 つの
sub-element アクションを期待します。 アクションは実行がノードに移動したときに実行されます。
actionhandler に記述したコードではどのような処理でも行えますが、 実行を伝播する必要がありま
す。 [3]
ビジネスアナリストにとって重要なロジックを実装するのにJavaAPIを利用するのであれば、 このノード
では利用できます。 ノードを利用することによって、ノードは、プロセスのグラフ表現中で可視化されま
す。 対照的に、ロジックがビジネスアナリストにとって重要でない場合、 Action(後述)に、プロセスのグ
ラフ表現中に見えないコードを追加することも可能です。
7.4. 遷 移 (transition)
遷移は、送り元ノードと送り先ノードを持っています。 送り元ノードは、from プロパティであらわされ
て、 送り先ノードは、toプロパティであらわされます。
遷移は、オプションで名前を持つことが可能です。 ほとんどの jBPM の機能は遷移名の一意性に依存して
いるということに注意してください。 もし、2つ以上の遷移が同じ名前を持つと、最初につけられたほう
が有効になります。 ノードに重複する遷移名がある場合、Map getLeavingT ransitionsMap() メ
ソッドは、 List getLeavingT ransitions() より少ない要素を返します。
72
第7章 プロセスのモデリング
デフォルト遷移は、リストにある最初の遷移です。
7.5. Action
Action は、プロセス実行中のイベントで実行される java コードの一部です。 グラフは、ソフトウェア要
件に関するコミュケーションの重要な道具です。 しかし、グラフは、作成されるソフトウェアの単なる
ビュー(投影)にすぎません。 それは、たくさんの技術的な詳細を隠蔽します。 Action は、グラフ表現とは
別に、技術的な詳細を追加するメカニズムです。 グラフがデプロイされると、Action を追加することが可
能です。 これは、グラフの構造を変更することなく、グラフとjavaコードの関連が可能であることを意味
します。 主なイベントタイプは、ノード入場時、ノード退場時、遷移取得時です。
イベントに配置されたアクションと、ノードに配置されたアクションの違いに注意してください。 イベン
トに配置されたアクションは、 イベントのトリガ時に実行されます。 イベントトリガ時のアクション
は、 プロセスの制御フローに影響しません。 オブザーバーパターンに似ています。 一方で、 ノード [4] に
配置されたアクションは、実行 [5] を伝播する必要があります。
Let's look at an example of an action on an event. Suppose we want to do a database update on a given
transition. T he database update is technically vital but it is not important to the business analyst.
図 7.2 データベース更新 Action
public class RemoveEmployeeUpdate implements ActionHandler {
public void execute(ExecutionContext ctx) throws Exception {
// get the fired employee from the process variables.
String firedEmployee =
(String) ctx.getContextInstance().getVariable("fired employee");
// by taking the same database connection as used for the jbpm
// updates, we reuse the jbpm transaction for our database update.
Connection connection =
ctx.getProcessInstance().getJbpmSession().getSession().getConnection();
Statement statement = connection.createStatement();
statement.execute("DELETE FROM EMPLOYEE WHERE ...");
statement.execute();
statement.close();
}
}
73
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
<process-definition name="yearly evaluation">
<state name="fire employee">
<transition to="collect badge">
<action class="com.nomercy.hr.RemoveEmployeeUpdate" />
</transition>
</state>
<state name="collect badge">
</process-definition>
7.5.1. Action設定
カスタムアクションへの設定の追加とprocessdefinition.xm l での設定方法については、 「委譲設
定」 を参照してください。
7.5.2. Action参照
Actionには、名前をつけることが可能です。 名前付きActionは、Actionを指定可能な他の場所から参照が
可能です。 名前付きActionは、プロセス定義の中で子要素とすることも可能です
Action設定の重複に制限を設けたい場合、 この機能は、関心をひきます(例えば、Actionの設定が複雑なと
き)。 他のユースケースは、実行時のAction実行、スケジューリングです。
7.5.3. イベント
イベントはプロセスの実行時の瞬間を指定できます。 jBPM エンジンはグラフ実行中にイベントを起こし
ます。 これは、jbpm が次の状態を導出するときに起きます (参照:シグナル処理)。 イベントはプロセス定
義、ノード、遷移のようなプロセス定義上の要素にいつも関連しています。ほとんどのプロセス要素は、
異なるイベントタイプを起こせます。 例えばノードは、node-enter イベントと、 node-leave イベ
ントが起こせます。 イベントは、 Action のためのフックです。 各イベントは、Action のリストを持ちま
す。 jBPM エンジンがイベントを起こす時、Action のリストが実行されます。
7.5.4. イベント伝播
親状態は、プロセス定義の要素に親子関係を作成します。 親状態に含まれるノードと遷移は、その親とし
て、親状態を持ちます。 トップレベルの要素は、その親としてプロセス定義をもちます。 そのプロセス
定義は、親をもちません。 イベントが発生したとき、そのイベントは親階層に伝播されます。 これは、
例えば、プロセス内でのすべての遷移イベントを捕捉したり、 集中化された場所でこれらのイベントと
Actionの関連づけを可能にします。
7.5.5. スクリプト
スクリプトは、beanshellスクリプトを実行するActionです。 beanshellについてのより詳細の説明
は、beanshell のwebサイトを参照ください。 デフォルトでは、 すべてのプロセス変数は、スクリプト変
数として使用可能で、スクリプト変数は、プロセス変数には書けません。 また、以下のスクリプト変数が
使用可能です。
executionContext
token
node
task
taskInstance
74
第7章 プロセスのモデリング
<process-definition>
<event type="node-enter">
<script>
System.out.println("this script is entering node "+node);
</script>
</event>
...
</process-definition>
スクリプトに変数を取得や保存をする振る舞いをカスタマイズするために、 variable 要素はスクリプ
トの副要素として利用可能です。 この場合、 スクリプト表記は、スクリプトの副要素: expression に
置かなければいけません。
<process-definition>
<event type="process-end">
<script>
<expression>
a = b + c;
</expression>
<variable name='XXX' access='write' mapped-name='a' />
<variable name='YYY' access='read' mapped-name='b' />
<variable name='ZZZ' access='read' mapped-name='c' />
</script>
</event>
...
</process-definition>
スクリプトが開始する前に、 プロセス変数YYYとZZZは、 それぞれ、スクリプト変数bとcとして、 スク
リプトで使用可能です。 スクリプトが終了後、 そのスクリプト変数aは、プロセス変数XXXに保存されま
す。
If the access attribute of variable contains 'read', the process variable will be loaded as a scriptvariable before script evaluation. If the access attribute contains 'write', the script-variable will be
stored as a process variable after evaluation. T he attribute m apped-nam e can make the process
variable available under another name in the script. T his can be handy when your process variable
names contain spaces or other invalid script-literal-characters.
7.5.6. カスタムイベント
Note that it's possible to fire your own custom events at will during the execution of a process. Events
are uniquely defined by the combination of a graph element (nodes, transitions, process definitions and
superstates are graph elements) and an event-type (java.lang.String). jBPM defines a set of events that
are fired for nodes, transitions and other graph elements. But as a user, you are free to fire your own
events. In actions, in your own custom node implementations, or even outside the execution of a process
instance, you can call the GraphElem ent.fireEvent(String eventT ype, ExecutionContext
executionContext);. T he names of the event types can be chosen freely.
7.6. 親 状 態 (superstate)
親状態は、ノードのグループです。 親状態は、繰り返しネストすることも可能です。 親状態は、プロセ
ス定義に階層をもたせるのに利用可能です。 例えば、ある局面では、ひとつのアプリケーションが、プロ
セスの全ノードをグループ化することも可能です。 Action は、親状態のイベントと関連づけられます。
その結果、トークンは、ある瞬間に複数のネストしたノード中に存在することが可能です。 これは、実行
プロセスが、例えばスタートアップフェーズにあるかどうかチェックするのに便利です。 jBPM モデルで
は、親状態中のノードのグループ化は自由にできます。
75
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
7.6.1. 親状態 - 遷移 (transition)
親状態を退場するすべての遷移は、親状態に含まれるノード中のトークンによって取得可能です。 遷移
は、親状態に入場することも可能です。 その場合、親状態にある最初のノードにトークンはリダイレクト
されます。 親状態の外側のノードから親状態の内側のノードに直接遷移することも可能です。 逆に、親
状態の内側のノードから親状態の外側のノードの遷移も、また親状態そのものへの遷移も可能です。 親状
態は、自身の参照も持っています。
7.6.2. 親状態 - イベント (event)
親状態に特有な2つのイベントがあります。 superstate-enterとsuperstate-leaveです。 これら
のイベントは、ノードの入場、退場それぞれで発生します。 親状態内でトークンが遷移する限り、イベン
トは発生しません。
状態と、親状態の別々のイベントタイプを作成していることに注意してください。 これは、親状態イベン
トと、親状態内から伝播されるノードイベントを簡単に識別することができます。
7.6.3. 階層名 (hierarchical name)
Node names have to be unique in their scope. T he scope of the node is its node-collection. Both the
process definition and the superstate are node collections. T o refer to nodes in superstates, you have
to specify the relative, slash (/) separated name. T he slash separates the node names. Use '..' to refer
to an upper level. T he next example shows how to reference a node in a superstate:
<process-definition>
<state name="preparation">
<transition to="phase one/invite murphy"/>
</state>
<super-state name="phase one">
<state name="invite murphy"/>
</super-state>
</process-definition>
次のサンプルは親状態階層への参照の仕方をみせます。
<process-definition>
<super-state name="phase one">
<state name="preparation">
<transition to="../phase two/invite murphy"/>
</state>
</super-state>
<super-state name="phase two">
<state name="invite murphy"/>
</super-state>
</process-definition>
7.7. 例 外 ハ ン ド リ ン グ
jBPMの例外ハンドリングメカニズムはjavaの例外に当てはまります。 グラフ実行自身が問題の原因になる
ことは不可能です。 委譲クラスの例外だけが、例外を引き起こすことが可能です。
process-definition、node、及び transition、では、 exception-handler のリストを指定
できます。 各 exception-handler は、 Action のリストを持ちます。 委譲されたクラスで、例外が投
げられると、プロセス要素の親階層は、 適切な exception-handler を探します。 見つけたと
き、exception-handler の処理が実行されます。
76
第7章 プロセスのモデリング
jBPMの例外ハンドリングメカニズムは、 java例外ハンドリングとはまったく同じではないことに注意して
ください。 Javaでは、捕捉された例外は、制御フローに影響を与えます。 jBPMでは、制御フローをjBPM
例外ハンドリングメカニズムでは変更できません。 例外は、捕捉されるか否かのどちらかです。 捕捉さ
れない例外は、クライアント(例えば、token.signal()を呼んだクライアント)に投げられるか、 もし
くは、jBPM exception-handler によって捕捉されます。 捕捉される例外は、例外が起こらなかった
ようにグラフ実行を続けます。
例外を制御するActionでは、 T oken.setNode(Node node)で、 グラフにある任意のノードにトーク
ンをおくことも可能ということに注意してください。
7.8. プ ロ セ ス 包 含 (process composition)
プロセス包含は、process-state を用いてjBPM 内でサポートしています。 プロセス状態は他のプロセ
ス定義に関係している状態です。グラフ実行がプロセス状態に 入場するとき、 サブプロセスの新しいプ
ロセスインスタンスが作成されます。それは、プロセス状態に入場した実行パスに関係しています。 その
親プロセスの実行パスは、サブプロセスインスタンスが終了するまで待ちます。 サブプロセスインスタン
スが終了した時に、 親プロセスの実行パスはプロセス状態を退場し、親プロセスのグラフ実行を続けま
す。
<process-definition name="hire">
<start-state>
<transition to="initial interview" />
</start-state>
<process-state name="initial interview">
<sub-process name="interview" />
<variable name="a" access="read,write" mapped-name="aa" />
<variable name="b" access="read" mapped-name="bb" />
<transition to="..." />
</process-state>
...
</process-definition>
T his 'hire' process contains a process-state that spawns an 'interview' process. When execution
arrives in the 'first interview', a new execution (=process instance) of the 'interview' process is created. If
no explicit version is specified, the latest version of the sub process as known when deploying the 'hire'
process is used. T o make jBPM instantiate a specific version the optional version attribute can be
specified. T o postpone binding the specified or latest version until actually creating the sub process, the
optional binding attribute should be set to late. T hen variable 'a' from the hire process is copied into
variable 'aa' from the interview process. T he same way, hire variable 'b' is copied into interview variable
'bb'. When the interview process finishes, only variable 'aa' from the interview process is copied back
into the 'a' variable of the hire process.
一般的に、サブプロセスが開始したとき、 すべての read アクセスを持った variable は、親プロセス
から読み込まれ、 開始状態を退場するためにシグナルが渡させる前に、新しく作成されたサブプロセスに
与えられます。 サブプロセスインスタンスが終了する時に、すべての write アクセスを持った
variable は、 サブプロセスから親プロセスにコピーされます。 variable 要素の m apped-nam e 属
性により、サブプロセスで利用する変数名の指定が可能になります。
7.9. カ ス タ ム ノ ー ド の 振 る 舞 い
In jBPM, it's quite easy to write your own custom nodes. For creating custom nodes, an implementation of
the ActionHandler has to be written. T he implementation can execute any business logic, but also has
the responsibility to propagate the graph execution. Let's look at an example that will update an ERP-
77
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
system. We'll read an amount from the ERP-system, add an amount that is stored in the process
variables and store the result back in the ERP-system. Based on the size of the amount, we have to
leave the node via the 'small amounts' or the 'large amounts' transition.
図 7.3 更新 ERPサンプルプロセス抜粋
public class AmountUpdate implements ActionHandler {
public void execute(ExecutionContext ctx) throws Exception {
// business logic
Float erpAmount = ...get amount from erp-system...;
Float processAmount = (Float) ctx.getContextInstance().getVariable("amount");
float result = erpAmount.floatValue() + processAmount.floatValue();
...update erp-system with the result...;
// graph execution propagation
if (result > 5000) {
ctx.leaveNode(ctx, "big amounts");
} else {
ctx.leaveNode(ctx, "small amounts");
}
}
}
カスタムノード実装では、トークンの作成やジョインも可能です。 この方法の サンプルを見るために、
jBPM ソースコードにある Fork と Join のノードの 実装を調べてみましょう。
7.10. グ ラ フ 実 行 (graph execution)
jBPMのグラフ実行モデルは、 プロセス定義と、chain of commandパターンの解釈に基づいています。
Interpretation of the process definition means that the process definition data is stored in the database.
At runtime the process definition information is used during process execution. Note for the concerned :
we use Hibernate's second level cache to avoid loading of definition information at runtime. Since the
process definitions don't change (see process versioning) hibernate can cache the process definitions
in memory.
chain of commandパターンは、 グラフの各ノードは実行プロセスを伝播する責務があるという意味で
す。 ノードは実行処理を伝播しない場合、それは待機状態として振る舞います。
そのアイデアは、プロセスインスタンスで実行を開始し、 待機状態に入場するまで実行処理は継続してい
くというものです。
トークンは、実行のパスを表しています。 トークンは、プロセスグラフのノードへポインタを持ちます。
待機状態中、トークンは、データベースに永続可能です。 トークンの実行導出のアルゴリズムを見てみま
しょう。 実行は、シグナルがトークンに送られてきたときに開始します。 その後、実行は、chain of
command パターン経由で、 遷移とノードを通過します。 クラス図には関連するメソッドがあります。
78
第7章 プロセスのモデリング
図 7.4 メソッドに関係のあるグラフ実行
When a token is in a node, signals can be sent to the token. Sending a signal is an instruction to start
execution. A signal must therefore specify a leaving transition of the token's current node. T he first
transition is the default. In a signal to a token, the token takes its current node and calls the
Node.leave(ExecutionContext,T ransition) method. T hink of the ExecutionContext as a
T oken because the main object in an ExecutionContext is a T oken. T he
Node.leave(ExecutionContext,T ransition) method will fire the node-leave event and call
the T ransition.take(ExecutionContext). T hat method will fire the transition event and call
the Node.enter(ExecutionContext) on the destination node of the transition. T hat method will fire
the node-enter event and call the Node.execute(ExecutionContext). Each type of node has its
own behaviour that is implemented in the execute method. Each node is responsible for propagating
graph execution by calling the Node.leave(ExecutionContext,T ransition) again. In summary:
T oken.signal(T ransition)
--> Node.leave(ExecutionContext,T ransition)
--> T ransition.take(ExecutionContext)
--> Node.enter(ExecutionContext)
--> Node.execute(ExecutionContext)
Action 呼び出しを含む次の状態の導出のすべては、 クライアントのスレッドで行われていることに注意し
てください。 共通の誤解は、すべての導出がクライアントのスレッドにて行われなる必要があるというこ
とです。 さまざまな非同期呼び出しと同様に、非同期メッセージング(JMS)を利用できます。 プロセ
スインスタンスの更新として、同じトランザクション内でメッセージが送信されたとき、 すべての同期問
題は、対応されなければなりません。 いくつかのワークフローシステムは、グラフにあるすべてのノード
間で、 非同期メッセージングを利用します。 しかし、高いスループット環境では、 このアルゴリスム
は、ビジネスプロセスのパフォーマンス調整のために、より多くの制御と柔軟性をもたらします。
7.11. ト ラ ン ザ ク シ ョ ン 境 界 (transaction demarcation)
「グラフ実行(graph execution)」 と 3章グラフ指向プログラミング で説明したように、 jBPM はクライア
ントのスレッドでプロセスを実行し、 本質的に同期処理されます。 つまり、 token.signal() または
taskInstance.end() は、 プロセスが新しい待機状態になったときのみ返されます。
モデリングの観点からここで説明する jPDL 機能は、 「 非同期続行」 です。
ほとんどの状況で、もっとも素直なアプローチです。 なぜなら、実行プロセスは簡単にサーバーサイドの
トランザクションに結びつきます。: プロセスは、ある状態から次の状態にひとつのトランザクション内
で移動します。
インプロセスでの導出に時間がかかるいくつかのシナリオでは、 この振る舞いは、目的にそったものでは
ないかもしれません。 これに対処するのに、jBPM は非同期式のプロセスを継続する非同期メッセージン
グシステムを含んでいます。 もちろん、java エンタープライズ環境では、 jBPM は組み込みメッセージン
グシステムの代わりに、JMSメッセージブローカーを使うように設定可能です。
79
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
In any node, jPDL supports the attribute async="true". Asynchronous nodes will not be executed in
the thread of the client. Instead, a message is sent over the asynchronous messaging system and the
thread is returned to the client (meaning that the token.signal() or taskInstance.end() will
return).
BPMクライアントコードは、トランザクションをコミットできることに注意してください。 メッセージの
送信は、プロセスの更新と同じトランザクションで処理されるべきです。 そのトランザクションの結果
は、トークンが次のノードに移動(未実行)し、 org.jbpm .com m and.ExecuteNodeCom m andm essageが、 非同期メッセージングシステム上でjBPMコマンドエクセキュータに送られていきます。
jBPMコマンドエクセキュータは、キューからコマンドを読み込み、実行します。
org.jbpm .com m and.ExecuteNodeCom m and の場合、ノードの実行で、 プロセスが続いて行われま
す。 各コマンドは、別のトランザクションで実行されます。
非同期プロセスを継続するためには、jBPMコマンドエクセキュータの動作が必要となります。 この最も
簡単な方法は、webアプリケーションで CommandExecutionServletを設定することです。 それ以外で
は、Com m andExecutorが他の方法で稼動可能かを確かめなければなりません。
As a process modeler, you should not really be concerned with all this asynchronous messaging. T he
main point to remember is transaction demarcation: By default jBPM will operate in the transaction of the
client, doing the whole calculation until the process enters a wait state. Use async="true" to
demarcate a transaction in the process.
Let's look at an example:
<start-state>
<transition to="one" />
</start-state>
<node async="true" name="one">
<action class="com...MyAutomaticAction" />
<transition to="two" />
</node>
<node async="true" name="two">
<action class="com...MyAutomaticAction" />
<transition to="three" />
</node>
<node async="true" name="three">
<action class="com...MyAutomaticAction" />
<transition to="end" />
</node>
<end-state name="end" />
...
実行プロセス(開始と再開)と対話するクライアントコードは、 通常のプロセス(同期)との場合とまさに同
じです。
//start a transaction
JbpmContext jbpmContext = jbpmConfiguration.createContext();
try {
ProcessInstance processInstance =
jbpmContext.newProcessInstance("my async process");
processInstance.signal();
jbpmContext.save(processInstance);
} finally {
jbpmContext.close();
}
80
第7章 プロセスのモデリング
最初のトランザクション後、 プロセスインスタンスのルートトークンはノードoneに位置し、
ExecuteNodeCom m andm essageは、コマンドエクセキュータに送られていきます。
連続したトランザクションでは、 コマンドエクセキュータはキューからメッセージを読み込み、ノード
oneを実行します。 Actionは実行処理を伝播するか、もしくは、待機状態とするかを決定可能です。 も
し、Actionが実行処理を伝播することに決めた場合、 実行がノードtwoに入場したときに、遷移は終了し
ます、など、など。
[2] 3章グラフ指向プログラミング.
[3] 「ノード責務」.
[4] 「ノードタイプ - ノード(no d e)」.
[5] 「ノード責務」.
81
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
第 8章 コンテキスト
コンテキストは、プロセス変数に関するものです。 プロセス変数は、プロセスインスタンスに関係してい
る情報を維持するキー-値ペアになっています。 コンテキストは、データベースに保存できなければいけ
ないので、いくつか軽い制限が適用されます。
8.1. 変 数 へ の ア ク セ ス
org.jbpm.context.exe.ContextInstanceは、 プロセス変数と動作する上で、中心的なインターフェースとし
て役割を担っています。 ContextInstanceをProcessInstanceから、このように取得できます。
ProcessInstance processInstance = ...;
ContextInstance contextInstance = (ContextInstance)
processInstance.getInstance(ContextInstance.class);
最も基本的な操作は、これらです。
void ContextInstance.setVariable(String variableName, Object value);
void ContextInstance.setVariable(String variableName, Object value, Token token);
Object ContextInstance.getVariable(String variableName);
Object ContextInstance.getVariable(String variableName, Token token);
変数名は、java.lang.Stringです。 デフォルトでは、jBPMは、次の型をサポートしています。
java.lang.String
java.lang.Boolean
java.lang.Character
java.lang.Float
java.lang.Double
java.lang.Long
java.lang.Byte
java.lang.Short
java.lang.Integer
java.util.Date
byte[]
java.io.Serializable
Hibernate で永続化できるクラス
型のないnullを永続的に保存できます。
他のすべての型も、問題なく、プロセス変数に保存できます。 しかし、プロセスインスタンスにsaveし
ようとした時に、Exceptionを起こします。
変数にHibernate永続オブジェクトを保存するよう jBPM を設定するは、 Hibernate永続オブジェクトの保
存を参照してください。
8.2. 変 数 の 生 存 期 間
変数は、プロセスアーカイブの中で宣言されていなくていいです。 実行時、Javaオブジェクトを変数に置
くだけです。 その変数が存在していない場合には作成されます。 まさにjava.util.Mapと同じように
なります。
82
第8章 コンテキスト
変数は以下のメソッドで削除できます。
ContextInstance.deleteVariable(String variableName);
ContextInstance.deleteVariable(String variableName, Token token);
自動型変換はサポートされています。 これは、異なる型で上書きすることができるということです。 も
ちろん、データベース接続をより作成し、カラムの更新を行う型変換に制限を設けるようにするべきで
す。
8.3. 変 数 永 続 性
変数はプロセスインスタンスの一部です。 データベースにプロセスインスタンスを保存すると、 データ
ベースがプロセスインスタンスと同期されます。 データベースにプロセスインスタンスを保存 (更新) し
た結果としてデータベースから変数が作成、 更新、 および削除されます。詳細については、 5章永続性
を参照してください。
8.4. 変 数 ス コ ー プ
実行の各パス (read: token) は独自のプロセス変数セットを持ちます。 変数の要求は常にトークンで行わ
れます。 プロセスインスタンスはトークンのツリーを持ちます (3章グラフ指向プログラミング を参照)。
トークンを指定せずに変数を要求すると、 ルートトークンがデフォルトのトークンになります。
変数ルックアップは与えられたトークンの親上で再帰的に実行されます。その振る舞いは、プログラム言
語での変数のスコープと似ています。
存在していない変数がトークンにセットされた時、その変数は root-トークンに作成されます。 これは、
各変数はデフォルトでプロセススコープを持っているという意味です。 変数をトークンローカルにするに
は、以下を使用して明示的に作成しなければいけません。
ContextInstance.createVariable(String name, Object value, Token token);
8.4.1. 変数オーバーローディング
変数オーバーローディングは、 各実行パスが、同名の変数のコピーを持つことができるということです。
それらは、独立しているように扱われるため、異なるタイプであることができます。 変数オーバーロー
ディングは、 複数の並列実行パスを同一 遷移で処理する場合に、おもしろいかもしれません。 その複数
の実行パスを 唯一区別するものは、個々の変数のセットのみです。
8.4.2. 変数オーバーライディング
Variable overriding means that variables of nested paths of execution override variables in more global
paths of execution. Generally, nested paths of execution relate to concurrency : the paths of execution
between a fork and a join are children (nested) of the path of execution that arrived in the fork. For
example, if you have a variable 'contact' in the process instance scope, you can override this variable in
the nested paths of execution 'shipping' and 'billing'.
8.4.3. タスクインスタンス変数スコープ
タスクインスタンス変数の詳細については、 「タスクインスタンス変数」 を参照してください。
8.5. 一 時 変 数
When a process instance is persisted in the database, normal variables are also persisted as part of
83
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
the process instance. In some situations you might want to use a variable in a delegation class, but you
don't want to store it in the database. An example could be a database connection that you want to pass
from outside of jBPM to a delegation class. T his can be done with transient variables.
一時変数の生存期間は、プロセスインスタンスのJavaオブジェクトと一緒です。
それらの性質のため、一時変数はトークンには関係ありません。 したがって、プロセスインスタンスオブ
ジェクトの一時変数の1つのMapでしかありません。
T he transient variables are accessible with their own set of methods in the context instance, and don't
need to be declared in the processdefinition.xml
Object ContextInstance.getTransientVariable(String name);
void ContextInstance.setTransientVariable(String name, Object value);
8.6. カ ス タ マ イ ズ 変 数 永 続 性
変数はデータベースに2ステップで保存されます:
user-java-object <---> converter <---> variable instance
変数は、VariableInstance に保存されます。 そのVariableInstancesのフィールドは、 データ
ベースのフィールドに HibernateでMapされています。 jBPMのデフォルト設定では、 6種類の
VariableInstances が利用されています。
DateInstance (データベースのT ypes.T IMEST AMPにマッピングされるjava.lang.Dateフィールド)
DoubleInstance (データベースのT T ypes.Doubleにマッピングされるjava.lang.Doubleフィール
ド)
StringInstance (データベースのT ypes.VARCHARにマッピングされるjava.lang.Stringフィールド)
LongInstance (データベースのT ypes.BIGINT にマッピングされるjava.lang.Longフィールド)
HibernateLongInstance (Hibernate で永続化できる long idフィールドのタイプに使用されます。
java.lang.Object フィールドは、データベースの Hibernate エンティティへの参照にマッピングされま
す)
HibernateStringInstance (Hibernate で永続化できる long idフィールドのタイプに使用されま
す。 java.lang.Object フィールドは、データベースのHibernate エンティティへの参照にマッピングさ
れます)
コンバータ は、 javaオブジェクトと、VariableInstancesによって保存されるjavaオブジェクト間で
変換します。 したがって、プロセス変数が例えば、 ContextInstance.setVariable(String
variableNam e, Object value)でセットされるとき、 その値は、任意でコンバータで変換できま
す。 そして、変換されたオブジェクトは、VariableInstanceに保存されます。 コンバータは、次の
インターフェースの実装です。
public interface Converter extends Serializable {
boolean supports(Object value);
Object convert(Object o);
Object revert(Object o);
}
コンバータはオプションです。 コンバータは jBPM クラスローダーで利用できる必要があります。 詳細に
ついては、 「jBPMクラスローダ」 を参照してください。
どのように user-java-objects が変換され、 変数インスタンスに保存されるかはファイル
84
第8章 コンテキスト
org/jbpm /context/exe/jbpm .varm apping.properties で設定されます。 このプロパティファ
イルをカスタマイズするには、 「他の設定ファイル」 で説明したようにクラスパスのルートに変更され
たバージョンを指定します。 プロパティファイルの各行では 2 つまたは 3 つのクラス名をスペースで区
切って指定します (user-java-object のクラス名、 オプションでコンバータのクラス名と変数インスタン
スのクラス名)。 カスタムコンバータを参照する場合は、 カスタムコンバータが jBPM クラスパスに指定
されていることを確認します (「jBPMクラスローダ」 を参照)。 カスタム変数インスタンスを参照する場
合、 カスタム変数インスタンスは jBPM クラスパスに指定されている必要があります。 また、
org/jbpm /context/exe/VariableInstance.hbm .xm l の Hibernate マッピングファイルは、
VariableInstance のカスタムサブクラスを含むよう更新されている必要があります。
例えば、次の org/jbpm /context/exe/jbpm .varm apping.xm l のXML 一部を見てみてください。
<jbpm-type>
<matcher>
<bean class="org.jbpm.context.exe.matcher.ClassNameMatcher">
<field name="className"><string value="java.lang.Boolean" /></field>
</bean>
</matcher>
<converter
class="org.jbpm.context.exe.converter.BooleanToStringConverter" />
<variable-instance
class="org.jbpm.context.exe.variableinstance.StringInstance" />
</jbpm-type>
この snippet は、java.lang.Boolean のすべてのオブジェクトは、
BooleanT oStringConverter で変換し、 その変換後の String のオブジェクトは、 StringInstance
の型 のvaliable instance オブジェクトに保存されることを指定しています。
コンバータが指定されていない場合、 変数に格納された Long オブジェクトは変換されずに単にタイプ
LongInstance の変数インスタンスに格納されます。
<jbpm-type>
<matcher>
<bean class="org.jbpm.context.exe.matcher.ClassNameMatcher">
<field name="className">
<string value="java.lang.Long" />
</field>
</bean>
</matcher>
<variable-instance class="org.jbpm.context.exe.variableinstance.LongInstance"
/>
</jbpm-type>
85
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
第 9章 タスク管理
jBPM の中心機能は、実行プロセスを永続できることです。 この機能が極めて有用な状況は、タスク管理
とユーザ向けのタスクリストです。 jBPM は、ユーザのタスクのために待機状態を持つことができる全体
的なプロセスについて表現している 1つのソフトウェアを指定できるようにします。
9.1. タ ス ク
タスクは、プロセス定義の一部で、どのようにプロセス実行中に、 タスクインスタンスが作成、割り当て
られなかればいけないのか定義します。
タスクは、task-node と process-definition 内で定義できます。 最も一般的な方法は、単数又は
複数の task をtask-node で定義することです。 その場合、task-node は、 ユーザが行うタスクを表
現し、プロセス実行は、アクターがタスクを終了するまで待機するはずです。 アクターがタスクを終了し
た時、プロセス実行は、継続します。 task-node により多くのタスクが定義されたとき、 デフォルトの
振る舞いは、すべてのタスクが終了するのを待ちます。
タスクは、process-definition 上にも指定できます。 プロセス定義に指定されたタスクは、 名前で
ルックアップされ、task-node の中から参照されるか、 またはアクションの中から利用することができ
ます。 実は、すべての名前付きタスク(task-nodeでも)は、process-definition内で名前でルックアップで
きます。
タスク名は、プロセス定義全体で一意でなければいけません。 タスクには、priority を設定できま
す。 この優先順位は、このタスクのために作成される、 各タスクインスタンスに対して優先順位の初期
値として利用されます。 タスクインスタンスは、その後、この初期優先順位を変更できます。
9.2. タ ス ク イ ン ス タ ン ス
タスクインスタンスは、アクター ID (java.lang.String) に割り当てられます。 すべてのタスクインスタン
スは、データベースの1つのテーブル (JBPM_T ASKINST ANCE) に 保存されます。 既知のアクター ID の
ためにタスクインスタンス全体のこのテーブルを 検索することで、 その特定ユーザのタスクリストが取
得できます。
jBPMタスクリストメカニズムは、jBPMタスクと他のタスクの結合が可能です。 それは、それらのタスク
がプロセス実行と関係ないときでも可能です。 そのように、jBPM開発者は、1つの集中化されたタスク
リストリポジトリで、 容易に、jBPMプロセスタスクを他のアプリケーションのタスクに組み合わせるこ
とができます。
9.2.1. タスクインスタンスのライフサイクル
タスクインスタンスライフサイクルは、分かり易くなっています: 作成後、タスクインスタンスは、オプ
ションとして開始できます。 次に、タスクインスタンスは終了できます。これはタスクインスタンスが完
了としてマークされると言う意味です。
柔軟性のために、割り当ては、ライフサイクルの一部ではないことに留意してください。 ですので、タス
クインスタンスは、割り当てることも、割り当てないこともできます。 タスクインスタンス割り当ては、
タスクインスタンスライフサイクルに何の影響も与えません。
タスクインスタンスは、基本的に実行プロセスが task-node に入場することで作成されます。
(T askMgm tInstance.createT askInstance(...) メソッドで。) 次に、ユーザインターフェース
コンポーネントは、 T askMgm tSession.findT askInstancesByActorId(...) を使用してタスク
リストをデータベースで検索します。 次に、入力情報をユーザから収集したら、UI コンポーネントは、
T askInstance.assign(String)、T askInstance.start()、 あるいは
T askInstance.end(...) を呼び出します。
86
第9章 タスク管理
タスクインスタンスは、日付プロパティによってその状態を維持します: create、start そして end が
あります。 それらプロパティは、T askInstance の個々のGetter によりアクセス可能です。
現在は、終了タスクインスタンスは、終了日がマークされ、 その結果、以降のタスクリストの検索で取得
されません。 しかし、JBPM_T ASKINST ANCEテーブルには残っています。
9.2.2. タスクインスタンスとグラフ実行
T ask instances are the items in an actor's task list. T ask instances can be signalling. A signalling task
instance is a task instance that, when completed, can send a signal to its token to continue the process
execution. T ask instances can be blocking, meaning that the related token (=path of execution) is not
allowed to leave the task-node before the task instance is completed. By default task instances are
signalling and non-blocking.
2つ以上のタスクインスタンスがタスクノードに関連する場合、 プロセス開発者は、タスクインスタンス
の終了が、どうプロセスの継続に影響するかを指定することができます。 次は、タスクノードのsignalプ
ロパティの値のリストです。
last: デフォルトです。 最後のタスクインスタンスが終了するとき、実行を続けます。 このノード入
場にてタスクが作成されないとき、実行は継続されます。
last-wait: 最後のタスクインスタンスが終了するとき、実行を続けます。 このノード入場にてタスク
が作成されないときは、実行はタスクが作成されるまでタスクノードで待ちます。
first: 最初のタスクインスタンスが終了するとき、実行を続けます。 このノード入場にてタスクが作成
されないとき、実行は継続されます。
first-wait: 最初のタスクインスタンスが終了するとき、実行を続けます。 このノード入場にてタスク
が作成されないときは、実行はタスクが作成されるまでタスクノードで待ちます。
unsynchronized: タスクが作成されたり、もしくは終了していない状態とは関係なく、実行はいつも
継続します。
never: タスクが作成されたり、もしくは終了していない状態とは関係なく、実行は継続しません。
T ask instance creation might be based upon a runtime calculation. In that case, add an
ActionHandler on the node-enter event of the task-node and set the attribute createtasks="false". Here is an example of such an action handler implementation:
public class CreateTasks implements ActionHandler {
public void execute(ExecutionContext executionContext) throws Exception {
Token token = executionContext.getToken();
TaskMgmtInstance tmi = executionContext.getTaskMgmtInstance();
TaskNode taskNode = (TaskNode) executionContext.getNode();
Task changeNappy = taskNode.getTask("change nappy");
// now, 2 task instances are created for the same task.
tmi.createTaskInstance(changeNappy, token);
tmi.createTaskInstance(changeNappy, token);
}
}
サンプルにありますように、作成されるタスクは、タスクノードに指定されます。 それらは、プロセス定
義でも指定ができ、 T askMgm tDefinition からも取得できます。 T askMgm tDefinition は、タス
ク管理情報をもつように、 ProcessDefinitionを継承したものです。
タスクインスタンスが終了したとマークするためのAPIメソッドは、 T askInstance.end() です。 任意
で、endメソッドに遷移を指定できます。 タスクインスタンス完了が実行プロセスの継続を引き起こす場
87
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
合、 指定された遷移を通るため、そのタスクノードから退場します。
9.3. 割 り 当 て
A process definition contains task nodes. A task-node contains zero or more tasks. T asks are a static
description as part of the process definition. At runtime, tasks result in the creation of task instances. A
task instance corresponds to one entry in a person's task list.
With JBPM, push (personal task list) [6 ] and pull (group task list) [7] model (see below) of task
assignment can be applied in combination. T he process can calculate the responsible for a task and
push it in his/her task list. Or alternatively, a task can be assigned to a pool of actors, in which case
each of the actors in the pool can pull the task and put it in the actor's personal task list.
9.3.1. 割り当てインターフェース
タスクインスタンスの割り当ては、 Assignm entHandler インターフェース経由で行われます。
public interface AssignmentHandler extends Serializable {
void assign( Assignable assignable, ExecutionContext executionContext );
}
AssignmentHandler実装はタスクインスタンスが作成されたとき、呼び出されます。 その時、タスクイン
スタンスは、ひとり、もしくはそれ以上のアクターに割り当てられます。 Assignm entHandler 実装
は、 タスクを割り当てるために Assignable のメソッド ( setActorIdか setPooledActors )を呼ぶ
必要があります。 Assignable は、 T askInstance か Swim laneInstance (=プロセスロール)で
す。
public interface Assignable {
public void setActorId(String actorId);
public void setPooledActors(String[] pooledActors);
}
T askInstances と Swim laneInstances の両方は、 指定されたユーザか、アクターのプールに割り
当てられます。 ユーザに割り当てるために、Assignable.setActorId(String actorId) を呼び出
します。 プールのアクター候補に割り当てるために、 Assignable.setPooledActors(String[]
actorIds) を呼び出します。
プロセス定義の各タスクは、 実行時の割り当てを行うためにassignment handler実装と関係可能です。
プロセス内で複数のタスクが同じ人、もしくはアクターのグループに割り当てられるとき、 スイムレー
ン [8 ] の使用を考えます。
再利用可能な Assignm entHandler を作成できるようにするために、 Assignm entHandler の各使
用を processdefinition.xm l で設定できます。 割り当てハンドラへの設定の追加方法については、
「委譲」 を参照してください。
9.3.2. 割り当てデータモデル
アクターへのタスクインスタンスとスイムレーンインスタンスの割り当てを管理するためのデータモデル
は以下のとおりです。 各 T askInstance は、アクター ID と プールされたアクターのセットを保持して
います
88
第9章 タスク管理
図 9.1 割り当てモデルのクラス図
アクター IDは、タスクに関する責任がありますが、 プールされたアクターのセットは、タスクを取得す
れば、責任を負うことが可能な候補者のコレクションを表しています。 アクター IDとプールされたアク
ターは任意で設定ができ、組み合わせることも可能です。
9.3.3. パーソナルタスクリスト
T he personal task list denotes all the task instances that are assigned to a specific individual. T his is
indicated with the property actorId on a T askInstance. So to put a T askInstance in someone's
personal task list, you just use one of the following ways:
プロセスのtask要素の属性 actor-id に表現を指定する
コードの任意の場所で T askInstance.setActorId(String) を使用する
AssignmentHandler の assignable.setActorId(String)> を使用する
特定のユーザーのパーソナルタスクリストを取得するに
は、T askMgm tSession.findT askInstances(String actorId)を使用します。
9.3.4. グループタスクリスト
プールアクターは、タスクインスタンスの候補を意味します。つまり、タスクは多くのユーザーに提供さ
れ、1人の候補者が名乗りでてそのタスクを引き受けることになります。ユーザーはグループタスクリス
トのタスクをすぐに開始できません。なぜなら、多くのユーザーが同じタスクを開始するとコンフリクト
が発生するからです。これを回避するには、ユーザーがまずグループタスクリストのタスクインスタンス
を取得し、自分のパーソナルタスクリストに移動します。ユーザーは、自分のパーソナルタスクリストに
なるタスクのみを開始できます。
T o put a taskInstance in someone's group task list, you must put the user's actorId or one of the user's
groupIds in the pooledActorIds. T o specify the pooled actors, use one of the following:
プロセスのtask要素の属性pooled-actor-idsに式を指定する
コードの任意の場所から T askInstance.setPooledActorIds(String[]) を使用する
AssignmentHandler の assignable.setPooledActorIds(String[]) を使用する
T o fetch the group task list for a given user, proceed as follows: Make a collection that includes the
user's actorId and all the ids of groups that the user belongs to. With
T askMgm tSession.findPooledT askInstances(String actorId) or
T askMgm tSession.findPooledT askInstances(List actorIds) you can search for task
89
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
instances that are not in a personal task list (actorId==null) and for which there is a match in the pooled
actorIds.
T he motivation behind this is that we want to separate the identity component from JBPM task
assignment. JBPM only stores Strings as actorIds and doesn't know the relation between the users,
groups and other identity information.
T he actorId will always override the pooled actors. So a taskInstance that has an actorId and a list of
pooledActorIds, will only show up in the actor's personal task list. Keeping the pooledActorIds around
allows a user to put a task instance back into the group by just setting the actorId property of the
taskInstance to null.
9.4. タ ス ク イ ン ス タ ン ス 変 数
A task instance can have its own set of variables and a task instance can also 'see' the process
variables. T ask instances are usually created in an execution path (=token). T his creates a parent-child
relation between the token and the task instance similar to the parent-child relation between the tokens
themselves. T he normal scoping rules apply between the variables of a task instance and the process
variables of the related token. More info about scoping can be found in 「変数スコープ」.
T his means that a task instance can 'see' its own variables plus all the variables of its related token.
コントローラは、 タスクインスタンススコープとプロセススコープ化した変数の間で、 変数の作成、充
填、そして提出のために使用できます。
9.5. タ ス ク コ ン ト ロ ー ラ
タスクインスタンス作成時、 タスクコントローラは、タスクインスタンス変数の設定ができ、 タスクイ
ンスタンスが終了時、タスクコントローラは、 そのタスクインスタンスのデータをプロセス変数に渡すこ
とができます。
Note that you are not forced to use task controllers. T ask instances also are able to 'see' the process
variables related to its token. Use task controllers when you want to:
create copies of variables in the task instances so that intermediate updates to the task instance
variables don't affect the process variables until the process is finished and the copies are submitted
back into the process variables.
the task instance variables do not relate one-on-one with the process variables. E.g. suppose the
process has variables 'sales in January' 'sales in February' and 'sales in march'. T hen the form for
the task instance might need to show the average sales in the 3 months.
タスクはユーザからの入力を集めようとします。 しかし、タスクをユーザにみせるユーザインターフェー
スは、たくさんあります。 例えば、webアプリケーション、swingアプリケーション、インスタントマ
ネージャ、 eメールフォームなど。 タスクコントローラは、プロセス変数(=プロセスコンテキスト)と
ユーザインターフェースに橋を架けます。 タスクコントローラは、ユーザインターフェースアプリケー
ションにプロセス変数のビューを提供します。
タスクコントローラは、プロセス変数からタスク変数に変換します。 タスクインスタンスが作成されると
き、 タスクコントローラは、プロセス変数からの情報の抽出し、タスク変数を作成する責務をもちます。
タスク変数は、ユーザインターフェースフォームの入力として使用されます。 そして、ユーザ入力は、タ
スク変数に保存することができます。 ユーザがタスクを終了するとき、タスクコントローラは、 タスク
インスタンスのデータをもとに、プロセス変数の更新を行う責務があります。
90
第9章 タスク管理
図 9.2 タスクコントローラ
簡単なシナリオで、プロセス変数とフォームパラメータの間で1対1マッピングがあるとします。 タスク
コントローラは、task要素で指定されます。 この場合、デフォルトのjBPMタスクコントローラが利用さ
れ、中で変数 要素のリストを取得します。 その変数要素は、どのようにプロセス変数がタスク変数にコ
ピーされるかを表現しています。
次のサンプルは、プロセス変数に基づいて、 どのように別々のタスクインスタンス変数のコピーを作成す
るかを示しています。
<task name="clean ceiling">
<controller>
<variable name="a" access="read" mapped-name="x" />
<variable name="b" access="read,write,required" mapped-name="y" />
<variable name="c" access="read,write" />
</controller>
</task>
nam e 属性は、プロセス変数の名前をさしています。 m apped-nam e は、任意設定で、タスクインスタ
ンス変数の名前をさしています。 mapped- name 属性が省略された場合、mapped-nameの名前をデフォ
ルトにします。 mapped-name は、webアプリケーションのタスクインスタンスにあるフィールドのラベ
ルとしても 利用できるということに注意してください。
T he access attribute specifies if the variable is copied at task instance creation, will be written back to
the process variables at task end and whether it is required. T his information can be used by the user
interface to generate the proper form controls. T he access attribute is optional and the default access is
'read,write'.
タスクノード は、たくさんのタスクを持つことができ、 開始状態 は、ひとつのタスクをもてます。
If the simple one-to-one mapping between process variables and form parameters is too limiting, you can
also write your own T askControllerHandler implementation. Here's the T askControllerHandler interface:
public interface TaskControllerHandler extends Serializable {
void initializeTaskVariables(TaskInstance taskInstance, ContextInstance
contextInstance, Token token);
void submitTaskVariables(TaskInstance taskInstance, ContextInstance
contextInstance, Token token);
}
And here's how to configure your custom task controller implementation in a task:
91
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
<task name="clean ceiling">
<controller class="com.yourcom.CleanCeilingTaskControllerHandler">
-- here goes your task controller handler configuration -</controller>
</task>
9.6. ス イ ム レ ー ン
スイムレーンはプロセスロールであり、 プロセス内の複数のタスクを同じアクターが実行するよう指定す
るメカニズムです。 したがって、 あるスイムレーンに最初のタスクインスタンスが作成されたら、 同じ
スイムレーン内の以降のタスクすべてに対してプロセスでアクターを記憶する必要があります。 したがっ
て、 スイムレーンは 1 つの assignm ent [9 ] を持ち、スイムレーンを参照するすべてのタスクは
assignm ent [10 ] を指定しない必要があります。
スイムレーンで最初のタスクが作成されたとき、 スイムレーンの Assignm entHandler が呼び出され
ます。 Assignm entHandler に渡される Assignable は、 Swim laneInstance になります。 重要
なことは、任意の スイムレーンのタスクインスタンス上で行われる、 すべての割り当てはスイムレーン
インスタンスに伝播されるということです。 この振る舞いは、デフォルトで実装されていています。 な
ぜなら、あるプロセスのロールを遂行するために、タスクを行う人は、特定のプロセスの知識を持ってい
るためです。そのスイムレーンに対するすべての連結したタスクインスタンスの割り当ては、そのユーザ
に自動的に行われます。
スイムレーンはUMLアクティビティ図からきた用語です。
9.7. 開 始 タ ス ク の ス イ ム レ ー ン
スイムレーンは、プロセス開始者を捕捉するため、開始タスクと関係することが可能です。
開始状態ではタスクを指定できます。 そのタスクはスイムレーンに関連付けることができます。 このよ
うなタスクに新しいタスクインスタンスが作成された場合、 認証された現在のアクターは
Authentication.getAuthenticatedActorId()
納されます。
[11]
で取得され、 そのアクターは開始タスクのスイムレーンに格
例:
<process-definition>
<swimlane name='initiator' />
<start-state>
<task swimlane='initiator' />
<transition to='...' />
</start-state>
</process-definition>
また、 他のタスクと同様に、 開始タスクに編集を追加して、タスクに関連付けられた形式を定義するこ
ともできます。 「タスクコントローラ」 を参照してください。
9.8. タ ス ク イ ベ ン ト
タスクは、イベントと関係しているアクションを持てます。 タスクには4つの標準イベントタイプがあり
ます: task-create、 task-assign、 task-start と task-endです。
タスクインスタンスが作成されたとき、task-create のイベントが起きます。
92
第9章 タスク管理
タスクインスタンスが割り当てられているときに、task-assignのイベントが起きます。 このイベント
上で実行されるアクションでは、
executionContext.getT askInstance().getPreviousActorId() で前回アクターにアクセスで
きることに注意してください。
T askInstance.start() が呼ばれたときに、 task-start のイベントが起きます。 これは、ユーザが
このタスクインスタンスで動作開始しているということを指すのに利用されます。 タスクを開始すること
は任意です。
T askInstance.end(...) が呼ばれたときに、task-end のイベントはおきます。 これはタスクの終
了をマークします。 そのタスクが実行プロセスに関係している場合、この呼び出しは、実行プロセスの再
開を呼び出すかもしれません。
タスクにはイベントとアクションを関連付けることができるため、 例外ハンドラをタスクで指定すること
もできます。 例外処理の詳細については、 「例外ハンドリング」 を参照してください。
9.9. タ ス ク タ イ マ
ノードのように、タイマーもタスクに指定できます。 「タイマー」 を参照してください。
タスクのタイマーについての特別なことは、タスクタイマーの cancel-event が カスタマイズできるこ
とです。 デフォルトでは、タスク上のタイマーは、タスクが終了(=完了)したときにキャンセルされま
す。 しかし、タイマー上の cancel-event 属性で、プロセス開発者は、 例えば、task-assign か
task-start にそれをカスタマイズすることができます。 cancel-event は、複数イベントをサポート
します。 cancel-event 型は、属性にカンマ区切りのリストで指定することで、複数イベントを組み合
わせることができます。
9.10. タ ス ク イ ン ス タ ン ス の カ ス タ マ イ ズ
T ask instances can be customized. T he easiest way to do this is to create a subclass of
T askInstance. T hen create a org.jbpm .taskm gm t.T askInstanceFactory implementation and
configure it by setting the configuration property jbpm .task.instance.factory to the fully qualified
class name in the jbpm.cfg.xml. If you use a subclass of T askInstance, also create a Hibernate mapping
file for the subclass (using the Hibernate extends="org.jbpm .taskm gm t.exe.T askInstance").
T hen add that mapping file to the list of mapping files in the hibernate.cfg.xm l
9.11. ア イ デ ン テ ィ テ ィ コ ン ポ ー ネ ン ト
Management of users, groups and permissions is commonly known as identity management. JBPM
includes an optional identity component that can be easily replaced by a company's own identity data
store.
jBPM アイデンティティ管理コンポーネントは、組織モデルの知識を含みます。 タスク割り当ては、基本
的に組織的な知識をもって行われます。 つまり、これは、ユーザ、グループ、システム、そして、それら
の関係を説明する組織モデルの知識を暗示するものです。オプションとして、パーミッションとロールも
組織モデルに含めることが可能です。 あらゆる組織に合うような汎用組織モデルは、作成不可能であるこ
とが証明され、様々な学術研究の試みは失敗しました。
jBPM がこれを扱う方法は、アクターを実際のプロセス参加者として定義することです。 アクターは、ア
クターID と呼ばれる ID で認識されます。 jBPM は、アクターID についての 知識だけを持ち、 それらは最
大限の柔軟性の目的で、java.lang.String として表現されます。そのため、組織モデルやデータ構造
に関するいかなる知識も、jBPM コアエンジンの範疇ではありません。
93
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
JBPM jBPMの拡張として、jBPMは、(将来)、簡単なユーザ-ロールモデルを管理するコンポーネントを提
供します。 このユーザとロール間の多対多の関連は、J2EEやサーブレット仕様のものと同じモデルで、
新しい開発の出発点として役立つかもしれません。 貢献することに興味のある人は、より詳細な情報のた
めに、JBPM 問題追跡システムをチェックしてみてください。
Note that the user-roles model as it is used in the servlet, ejb and portlet specifications, is not sufficiently
powerful for handling task assignments. T hat model is a many-to-many relation between users and
roles. T his doesn't include information about the teams and the organizational structure of users
involved in a process.
9.11.1. アイデンティティモデル
図 9.3 アイデンティティモデルクラス図
黄色のクラスは、次に議論する割り当て式ハンドラのクラスと関連があります。
User は、ユーザかサービスを表します。 Group は、さまざまなユーザのグループです。 Group は、
チーム、ビジネスユニット、及び会社全体の関係をモデルするようにネストすることが可能です。 Group
は、 階層グループを区別するために、タイプを持っています (例えば、ヘアカラーグループ)。
Mem bership は、ユーザとグループ間で多対多関連を表しています。 メンバーシップは、会社でのポジ
ションを表すのに利用できます。 グループで遂行するユーザのロールを示すために、メンバーシップ名を
使用することができます。
9.11.2. 割り当て式
T he identity component comes with one implementation that evaluates an expression for the calculation
of actors during assignment of tasks. Here's an example of using the assignment expression in a
process definition:
<process-definition>
<task-node name='a'>
<task name='laundry'>
<assignment expression='previous --> group(hierarchy) --> member(boss)' />
</task>
<transition to='b' />
</task-node>
割り当て式のシンタックスはこのような感じです:
94
第9章 タスク管理
first-term --> next-term --> next-term --> ... --> next-term
where
first-term ::= previous |
swimlane(swimlane-name) |
variable(variable-name) |
user(user-name) |
group(group-name)
and
next-term ::= group(group-type) |
member(role-name)
9.11.2.1. 最初の条件 (First term)
式は、左から右に解決されていきます。 First-term(最初の条件)は、アイデンティティモデルに User か
Group を指定します。 連続する条件は、次の条件を、一時的なユーザかグループから導出します。
previousは、タスクが、現在の承認済アクターに割り当てられていることを意味します。 これは、プロ
セス中で前回のステップで動作したアクターということになります。
swim lane (swim lane-nam e)は、 ユーザやグループが、指定されたスイムレーンインスタンスから取
得されるということです。
variable(variable-nam e)は、ユーザやグループが指定された変数インスタンスから取得されると
いうことです。 変数インスタンスは、java.lang.String を含むことができます。 その場合、その
ユーザやグループがアイデンティティコンポーネントから取得されます。 もしくは、変数インスタンス
は、 ユーザ やグループ のオブジェクトを含みます。
user(user-nam e)は、 指定されたユーザは、アイデンティティコンポーネントから取得されるという
ことです。
group(group-nam e)は、 指定されたグループが、アイデンティティコンポーネントから取得されると
いうことです。
9.11.2.2. 次の条件 (Next term)
group(group-type)は、ユーザ取得を目的とし、グループを取得します。 前回の条件は、ユーザ を導
出する必要があることを意味します。 それは、ユーザ取得を目的とし、すべてのメンバーシップから指定
されたグループタイプによりグループを検索します。
m em ber(role-nam e)は、ユーザ取得を目的とし、与えられたロールを遂行するグループを取得しま
す。 前回の条件は Groupを導出する必要があることを意味します。 この条件は、指定されたロール名と
メンバーシップ名がマッチするグループからメンバーシップによりユーザを検索します。
9.11.3. アイデンティティコンポーネントの削除
When you want to use your own datasource for organizational information such as your company's user
database or LDAP system, you can just rip out the JBPM identity component. T he only thing you need to
do is make sure that you delete the line ...
<mapping resource="org/jbpm/identity/User.hbm.xml"/>
<mapping resource="org/jbpm/identity/Group.hbm.xml"/>
<mapping resource="org/jbpm/identity/Membership.hbm.xml"/>
95
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
唯一しなければいけないことは、 以下の行が hibernate.cfg.xm lから削除されていることを確認する
ことです。
ExpressionAssignm entHandler が、アイデンティティコンポーネントに依存しているので、 その
ままで、それを使用することは、できないでしょう。 ユーザデータストア
に、ExpressionAssignm entHandlerを再利用して、それをバインドしたい場合、
ExpressionAssignm entHandlerを拡張して、 getExpressionSessionメソッドをオーバーライ
ドできます。
protected ExpressionSession getExpressionSession(AssignmentContext
assignmentContext);
[6 ] 「パーソナルタスクリスト」.
[7] 「グループタスクリスト」.
[8 ] 「スイムレーン」.
[9 ] 「割り当て」.
[10 ] 「割り当て」.
[11] 「認証」.
96
第10章 ドキュメント管理
第 10章 ドキュメント管理
重要
この機能はまだ実験段階にあります。
この機能を有効にするには、hibernate.cfg.xml で以下の行をコメント解除する必要があります:
<mapping
resource="org/jbpm/context/exe/variableinstance/JcrNodeInstance.hbm.xml"/>
jBPM のドキュメント管理サポートは Java Content Repository に基づいています。これは、ドキュメント
管理システムを Java に統合する標準的な Java 仕様です。基本的な考えとして、jBPM は JCR ノードを
プロセス変数として格納することをサポートします。
ノードを格納するために、以下のようにノードからセッション、リポジトリ、パスが抽出されます:
Session session = node.getSession();
Repository repo = session.getRepository();
Workspace wspace = session.getWorkspace();
// THE NODE REPOSITORY AND WORKSPACE NAME GOT TO
// CORRESPOND WITH A JBPM SERVICE NAME
repository = repo.getDescriptor(Repository.REP_NAME_DESC);
workspace = wspace.getName();
path = node.getPath();
jBPM コンテキストサービスの名前はリポジトリの名前
(repository.getDescriptor(Repository.REP_NAME_DESC)) に対応する必要があります。これ
は、ノード変数が jBPM データベースからロードされるときに jbpm プロセス変数に格納された参照とリ
ポジトリを一致させるためです。JCR ノードプロセス変数が取得されるとき、jbpm コンテキストの各
サービス名と格納されたレポジトリとワークスペース名が一致するか照合されます。jbpm コンテキスト
サービスとJCR セッション/リポジトリの名前の照合は以下のように行われます:
if there is a jBPM context service named 'jcr' (lower case) that one will be taken
リポジトリ名に一致するサービス名が照合される
リポジトリ名で始まりワークスペース名で終わるサービスが照合され、リポジトリ名を持つサービス
よりも優先される
この機能の典型的な使用例はドキュメント承認プロセスです。ドキュメントは承認され、更新される必要
があります。このドキュメント (Wordドキュメントなど) は JCR-content-repository-node に格納できま
す。ノードにはドキュメントのすべてのバージョンが含まれます。したがって、後でドキュメントの履歴
バージョンを参照できます。
この機能は Jackrabbit でのみテストされました。ライブラリ依存関係の詳細については、JCR 実装に関す
るドキュメントを参照してください。
97
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
第 11章 スケジューラ
この章では、jBPMで、どのようにタイマーが動作するかを説明します。
プロセスのイベント上で、タイマーを作成することができます。 タイマーの期限が切れたときにアクショ
ンが実行される、もしくは遷移します。
11.1. タ イ マ ー
タイマーを指定する最も簡単な方法は、timer要素を、ノードに追加することです。
<state name='catch crooks'>
<timer name='reminder'
duedate='3 business hours'
repeat='10 business minutes'
transition='time-out-transition' >
<action class='the-remainder-action-class-name' />
</timer>
<transition name='time-out-transition' to='...' />
</state>
指定されたノードのタイマーは、ノード退場後には実行しません。 遷移とアクションは任意で指定できま
す。タイマー実行時に次のイベントが 連続して起きます。
tim er 型によってイベントがおきます。
actionが指定された場合に、そのアクションは実行されます。
遷移が指定された場合、指定された遷移上の実行処理を再開するために、 シグナルが送信されます。
すべてのタイマーは一意の名前を持たなければいけません。 tim er 要素に名前が指定されていない場
合、 ノードの名前をタイマーの名前とします。
タイマーアクションは、例えば action や script のようなaction要素をサポートしています。
タイマーは、アクションで作成及びキャンセルされることになります。 その2つのaction 要素
は、create-tim er とcancel-tim er です。実際には、上記の timer 要素は、node-enter 時の
create-timer アクションと、node-leave 時の cancel-timer アクションの短い表記なのです。
11.2. ス ケ ジ ュ ー ラ デ プ ロ イ メ ン ト
プロセス実行はタイマーを作成、キャンセルします。 タイマーは、タイマーストアに保存されます。
別々のタイマーランナーは、必要時にタイマーストアをチェック、実行しなければいけません。
98
第11章 スケジューラ
図 11.1 スケジューラコンポーネント概要
99
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
第 12章 非同期継続
12.1. コ ン セ プ ト
jBPM is based on Graph Oriented Programming (GOP). Basically, GOP specifies a simple state machine
that can handle concurrent paths of execution. But in the execution algorithm specified in GOP, all state
transitions are done in a single operation in the thread of the client. If you're not familiar with the
execution algorithm defined in 3章グラフ指向プログラミング, please read that first. By default, this
performing state transitions in the thread of the client is a good approach because it fits naturally with
server side transactions. T he process execution moves from one wait state to another wait state in one
transaction.
But in some situations, a developer might want to fine-tune the transaction demarcation in the process
definition. In jPDL, it is possible to specify that the process execution should continue asynchronously
with the attribute async="true". async="true" is supported only when it is triggered in an event but
can be specified on all node types and all action types.
12.2. サ ン プ ル
Normally, a node is always executed after a token has entered the node. So the node is executed in the
thread of the client. We will explore asynchronous continuations by looking at two examples. T he first
example is part of a process with 3 nodes. Node 'a' is a wait state, node 'b' is an automated step and
node 'c' is again a wait state. T his process does not contain any asynchronous behavior and it is
represented in the picture below.
T he first frame shows the starting situation. T he token points to node 'a', meaning that the path of
execution is waiting for an external trigger. T hat trigger must be given by sending a signal to the token.
When the signal arrives, the token will be passed from node 'a' over the transition to node 'b'. After the
token arrived in node 'b', node 'b' is executed. Recall that node 'b' is an automated step that does not
behave as a wait state (e.g. sending an email). So the second frame is a snapshot taken when node 'b'
is being executed. Since node 'b' is an automated step in the process, the execute of node 'b' will include
the propagation of the token over the transition to node 'c'. Node 'c' is a wait state so the third frame
shows the final situation after the signal method returns.
100
第12章 非同期継続
図 12.1 サンプル1:非同期続行無しプロセス
While persistence is not mandatory in jBPM, the most common scenario is that a signal is called within a
transaction. Let's have a look at the updates of that transaction. First of all, the token is updated to point
to node 'c'. T hese updates are generated by Hibernate as a result of the
GraphSession.saveProcessInstance on a JDBC connection. Second, in case the automated
action would access and update some transactional resources, those transactional updates should be
combined or part of the same transaction.
T he second example is a variant of the first and introduces an asynchronous continuation in node 'b'.
Nodes 'a' and 'c' behave the same as in the first example, namely they behave as wait states. In jPDL a
node is marked as asynchronous by setting the attribute async="true".
T he result of adding async="true" to node 'b' is that the process execution will be split up into 2
parts. T he first part will execute the process up to the point where node 'b' is to be executed. T he
second part will execute node 'b' and that execution will stop in wait state 'c'.
T he transaction will hence be split into two separate transactions, one for each part. While it requires an
external trigger (the invocation of the T oken.signal method) to leave node 'a' in the first transaction,
jBPM will automatically trigger and perform the second transaction.
101
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
図 12.2 非同期続行のプロセス
For actions, the principle is similar. Actions that are marked with the attribute async="true" are
executed outside of the thread that executes the process. If persistence is configured (it is by default),
the actions will be executed in a separate transaction.
jBPMでは、非同期続行は非同期メッセージングシステムの利用によって実現されます。 プロセス実行が
非同期で実行されるところに到着したときに、 jBPMは、そのプロセスの中止、メッセージコマンドの作
成、そして、コマンドエクセキュータにメッセージコマンドを送ります。 コマンドエクセキュータはメッ
セージを受け取り次第、中断したプロセス実行を再開できる依存のないコンポーネントです。
jBPM は、JMS プロバイダ、もしくは組み込み非同期メッセージングシステムの利用を設定できます。 組
み込み非同期メッセージングシステムは、機能的に制限が結構ありますが、JMS が利用できない環境でも
この機能をサポートします。
12.3. ジ ョ ブ エ ク ス キ ュ ー タ
ジョブエクスキュータは、 プロセス実行を非同期に再開するコンポーネントです。 非同期メッセージシ
ステムを介してコマンドメッセージが到着するまで待機し、 実行します。非同期続行に使用される 2 つの
ジョブは ExecuteNodeJob と ExecuteActionJob です。
これらのジョブメッセージは、 プロセス実行により生成されます。 プロセス実行中に、 非同期で実行す
る必要がある各ノードまたはアクションに対して Job (POJO) が MessageService にディスパッチさ
れます。 メッセージサービスは Jbpm Context と関連付けられ、 送信する必要があるすべてのメッセー
ジを収集します。
102
第12章 非同期継続
メッセージは Jbpm Context.close() の一部として送信されます。 このメソッドは関連付けられたす
べてのサービスに対して close() 呼び出しをカスケード処理します。 実際のサービスは
jbpm .cfg.xm l で設定できます。 サービスの 1 つ DbMessageService はデフォルトで設定され、 新
しいジョブメッセージが利用可能であることをジョブエクスキュータに通知します。
T he graph execution mechanism uses the interfaces MessageServiceFactory and
MessageService to send messages. T his is to make the asynchronous messaging service
configurable (also in jbpm .cfg.xm l). In Java EE environments, the DbMessageService can be
replaced with the Jm sMessageService to leverage the application server's capabilities.
Here's how the job executor works in a nutshell:
ジョブはデータベースのレコードです。 ジョブはオブジェクトであり、 実行できます。 タイマーと非同
期メッセージはジョブです。 非同期メッセージの場合、 dueDate はメッセージが挿入されたときに単に
現在の時間に設定されます。 ジョブエクスキュータはジョブを実行する必要があります。 これは次の 2
つのフェーズで行われます。
ジョブエクセキュータスレッドはジョブを取得する必要がある
ジョブを取得したスレッドがジョブを実行する必要がある
Acquiring a job and executing the job are done in 2 separate transactions. A thread acquires a job by
putting its name into the owner field of the job. Each thread has a unique name based on IP address and
sequence number. Hibernate's optimistic locking is enabled on Job-objects. So if 2 threads try to acquire
a job concurrently, one of them will get a StaleObjectException and rollback. Only the first one will
succeed. T he thread that succeeds in acquiring a job is now responsible for executing it in a separate
transaction.
スレッドはジョブの取得と実行の間に消失する可能性があります。このような状況をクリアする ために、
1つのジョブエクセキュータごとにロック時間をチェックする 1つのロックモニタスレッドが存在しま
す。デフォルトでは、30 分以上ロックされているジョブは他のジョブがそのジョブを実行できるよう
ロック解除されます。
T he isolation level must be set to REPEAT ABLE_READ for Hibernate's optimistic locking to work
correctly. REPEAT ABLE_READ guarantees that this query will only update one row in exactly one of the
competing transactions.
update JBPM_JOB job
set job.version = 2
job.lockOwner = '192.168.1.3:2'
where
job.version = 1
Non-Repeatable Reads means that the following anomaly can happen: A transaction re-reads data it
has previously read and finds that data has been modified by another transaction, one that has been
committed since the transaction's previous read.
Non-Repeatable Reads はオプティミスティックロックにとって問題です。 分離レベル
READ_COMMIT T ED は Non-Repeatable Reads の発生を許すため、 十分ではありません。したがって、
複数のジョブエクセキュータスレッドを設定する場合はREPEAT ABLE_READ が必要です。
12.4. jBPM's built-in asynchronous messaging
When using jBPM's built-in asynchronous messaging, job messages will be sent by persisting them to
the database. T his message persisting can be done in the same transaction or JDBC connection as the
103
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
jBPM process updates.
そのコマンドメッセージは、JBPM_MESSAGEテーブルに保存されます。
POJOコマンドエクセキュータ(org.jbpm .m sg.com m and.Com m andExecutor)は、データベースの
テーブルからメッセージを読み取り、実行します。 つまり、典型的な POJO コマンドエクセキュータの
トランザクションは以下のようになります。
1. 次のコマンドメッセージの読み込み
2. コマンドメッセージの実行
3. コマンドメッセージの削除
コマンドメッセージの実行処理が失敗した場合、トランザクションはロールバックされます。 その後、新
しいトランザクションは、開始され、エラーメッセージをデータベースのメッセージに追加します。 コマ
ンドエクセキュータは、例外を含むすべてのメッセージを無視します。
図 12.3 POJO コマンドエクセキュータトランザクション
例外をコマンドメッセージに追加するトランザクションが失敗した場合は、ロールバックされます。 その
場合、例外もなくメッセージはキューに残り、後にリトライされます。
重要
jBPM's built-in asynchronous messaging system does not support multi-node locking. You cannot
just deploy the POJO command executor multiple times and have them configured to use the
same database.
104
第13章 ビジネスカレンダ
第 13章 ビジネスカレンダ
この章では、jBPMのビジネスカレンダを説明します。 ビジネスカレンダは、営業時間を知っていて、タ
スクとタイマーの期限の導出にも利用できます。
T he business calendar is able to calculate a due date by adding a duration to or subtracting it from a
base date. If the base date is omitted, the 'current' date is used.
13.1. Duedate( 期 限 )
前述の通り、 期限は期間と基準日で構成されます。 基準日の指定がない場合、 期間は期限を計算する際
の日付と時刻に対する期間となります。 形式は次の通りです。
duedate ::= [<basedate> +/-] <duration>
13.1.1. Duration (期間)
A duration is specified in absolute or in business hours. Let's look at the syntax:
duration ::= <quantity> [business] <unit>
Where <quantity> is a piece of text that is parsable with Double.parseDouble(quantity).
<unit> is one of {second, seconds, minute, minutes, hour, hours, day, days, week, weeks, month,
months, year, years}. And adding the optional indication business means that only business hours
should be taken into account for this duration. Without the indication business, the duration will be
interpreted as an absolute time period.
13.1.2. 基準日
A duration is specified in absolute or in business hours. Let's look at the syntax:
basedate ::= <EL> +/Where <EL> is any JAVA Expression Language expression that resolves to a Java Date or Calendar
object. Referencing variable of other object types,even a String in a date format like '2036-02-12', will
throw a Jbpm Exception.
この基準日は、 簡単なタイマー、 タスクのリマインダ、 タスク内タイマーの duedate 属性でサポート
されます。 これら要素の repeat 属性ではサポートされません。
13.1.3. 使用例
以下は可能な使用例です。
105
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
<timer name="daysBeforeHoliday" duedate="5 business days">...</timer>
<timer name="pensionDate" duedate="#{dateOfBirth} + 65 years" >...</timer>
<timer name="pensionReminder" duedate="#{dateOfPension} - 1 year" >
...
</timer>
<timer name="fireWorks" duedate="#{chineseNewYear} repeat="1 year" >
...
</timer>
<reminder name="hitBoss" duedate="#{payRaiseDay} + 3 days"
repeat="1 week" />
13.2. カ レ ン ダ 設 定
org/jbpm /calendar/jbpm .business.calendar.properties のファイルは、営業時間を指定し
ます。 そのファイルは、設定でき、修正したコピーはクラスパスが通っているところに置いて利用できま
す。
これは、jbpm .business.calendar.properties に、 デフォルトで設定されている営業時間の仕様
のサンプルです。
106
第13章 ビジネスカレンダ
hour.format=HH:mm
#weekday ::= [<daypart> [& <daypart>]*]
#daypart ::= <start-hour>-<to-hour>
#start-hour and to-hour must be in the hour.format
#dayparts have to be ordered
weekday.monday=
9:00-12:00 & 12:30-17:00
weekday.tuesday=
9:00-12:00 & 12:30-17:00
weekday.wednesday= 9:00-12:00 & 12:30-17:00
weekday.thursday= 9:00-12:00 & 12:30-17:00
weekday.friday=
9:00-12:00 & 12:30-17:00
weekday.saturday=
weekday.sunday=
day.format=dd/MM/yyyy
# holiday syntax: <holiday>
# holiday period syntax: <start-day>-<end-day>
# below are the belgian official holidays
holiday.1= 01/01/2005 # nieuwjaar
holiday.2= 27/3/2005 # pasen
holiday.3= 28/3/2005 # paasmaandag
holiday.4= 1/5/2005
# feest van de arbeid
holiday.5= 5/5/2005
# hemelvaart
holiday.6= 15/5/2005 # pinksteren
holiday.7= 16/5/2005 # pinkstermaandag
holiday.8= 21/7/2005 # my birthday
holiday.9= 15/8/2005 # moederkesdag
holiday.10= 1/11/2005 # allerheiligen
holiday.11= 11/11/2005 # wapenstilstand
holiday.12= 25/12/2005 # kerstmis
business.day.expressed.in.hours=
8
business.week.expressed.in.hours=
40
business.month.expressed.in.business.days= 21
business.year.expressed.in.business.days= 220
107
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
第 14章 Email サポート
この章では、 jBPM jPDLでのEmailサポートについて説明します。
14.1. jPDLで の Email
Emailをプロセスからいつ送信するかを指定するには4つの方法があります。
14.1.1. mailアクション
mail アクションは、プロセスグラフでこの Email の送信をノードとして表示しない場合に使用します。
プロセスでアクションをどこにでも指定できるので、例えば以下のようにmailアクションを指定できま
す。
<mail actors="#{president}" subject="readmylips" text="nomoretaxes" />
以下のようにsubject属性とtext属性を要素として指定することもできます。
<mail actors="#{president}" >
<subject>readmylips</subject>
<text>nomoretaxes</text>
</mail>
各フィールドにはJSFのような式を格納できます。以下に例を示します。
<mail to='#{initiator}' subject='websale'
text='your websale of #{quantity} #{item} was approved' />
式に関する詳細は、「式」を参照ください。
受信者を指定するには、actors と to の 2 つの属性があります。 to 属性はセミコロンで区切られた電
子メールアドレスのリストに解決する必要があります。 actors 属性はセミコロンで区切られたアクター
ID のリストに解決する必要があります。 これらのアクター ID はアドレス解決 (「アドレス解決」) によっ
て電子メールアドレスに解決されます。
<mail to='[email protected]' subject='urgent'
text='the mailserver is down :-)' />
受信者の指定方法の詳細については、 「メール受信者の指定」 を参照してください。
mailはテンプレートで定義でき、プロセスで以下のようにテンプレートのプロパティを上書きできます。
<mail template='sillystatement' actors="#{president}" />
テンプレートの詳細については、 「メールテンプレート」 を参照してください。
14.1.2. メールノード
メールアクションと同様に、Email の送信はノードとしてもモデリングできます。この場合、ランタイム
の動作は同じですが、プロセスグラフで Email がノードとして表示されます。
メールノードによってサポートされる属性と要素はメールアクション (「mailアクション」) とまったく同
じです。
108
第14章 Email サポート
<mail-node name="send email" to="#{president}"
subject="readmylips" text="nomoretaxes">
<transition to="the next node" />
</mail-node>
メールノードは退場遷移を1つだけ持つべきです。
14.1.3. タスクアサインメール
A notification email can be sent when a task gets assigned to an actor. Just use the notify="yes"
attribute on a task like this:
<task-node name='a'>
<task name='laundry' swimlane="grandma" notify='yes' />
<transition to='b' />
</task-node>
yes、 true、 または on に通知を設定すると、 jBPM が、 このタスクに割り当てられるアクターに電子
メールを送信します。 電子メールはテンプレートに基づき (「メールテンプレート」 を参照)、 Web アプ
リケーションのタスクページへのリンクを含みます。
14.1.4. タスクリマインダメール
割り当てと同様に、Email をタスクリマインダとして送信できます。jPDL のrem inder 要素はタイマー
に基づいています。最も一般的な属性はduedate と repeat です。唯一の違いはアクションを指定する
必要があるかどうかです。
<task-node name='a'>
<task name='laundry' swimlane="grandma" notify='yes'>
<reminder duedate="2 business days" repeat="2 business hours"/>
</task>
<transition to='b' />
</task-node>
14.2. メ ー ル で の 式
フィールド to、 recipients、 subject、 および text には、 JSF 形式の式を含めることができま
す。 式の詳細については、 「式」 を参照してください。
式の変数はスイムレーン、プロセス変数、jbpm .cfg.xm lで設定された一時変数Beanなどです。
これらの式は、 アドレス解決と組み合わせることができます。 詳細については、 「アドレス解決」 を参
照してください。 たとえば、 プロセスに president という名前のスイムレーンがあるとします。 次の電
子メール指定を確認してください。
<mail actors="#{president}" subject="readmylips" text="nomoretaxes" />
これにより、この特定のプロセス実行で president としての役目をする人にEmail が送信されます。
14.3. メ ー ル 受 信 者 の 指 定
14.3.1. 複数の受信者
actorsフィールドとtoフィールドでは、複数の受信者をセミコロン(;)またはコロン(:)で区切ることがで
109
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
きます。
14.3.2. アドレス解決
jBPM ではすべてアクターはアクター ID によって参照されます。これはプロセス参加者の ID として使用
する文字列です。アドレスリゾルバはアクター ID を Email アドレスに変換します。
Use the attribute actors in case you want to apply address resolving and use the attribute to in case you
are specifying email addresses directly and don't want to apply address resolving.
アドレス解決は以下のインターフェースを実装する必要があります。
public interface AddressResolver extends Serializable {
Object resolveAddress(String actorId);
}
アドレスリゾルバは、String、Stringのコレクション、またはStringの配列の3つのデータ型のいずれかを
返す必要があります。すべての文字列は指定されたアクターIDのEmailアドレスを表します。
アドレスリゾルバ実装は、名前jbpm .m ail.address.resolverを持つjbpm.cfg.xmlで設定されたbean
である必要があります。以下に例を示します。
<jbpm-configuration>
<bean name='jbpm.mail.address.resolver'
class='org.jbpm.identity.mail.IdentityAddressResolver' singleton='true' />
</jbpm-configuration>
T he identity component of jBPM includes an address resolver. T hat address resolver will look for the
User of the given actorId. If the user exists, the user's email is returned, otherwise null. More on the
identity component can be found in 「アイデンティティコンポーネント」.
14.4. メ ー ル テ ン プ レ ー ト
メールはprocessdefinition.xmlではなく、テンプレートファイルで指定できます。テンプレートを使用し
ても、各フィールドはprocessdefinition.xmlで上書きできます。メールテンプレートは以下のようにXML
ファイルで指定する必要があります。
110
第14章 Email サポート
<mail-templates>
<variable name="BaseTaskListURL"
value="http://localhost:8080/jbpm/task?id=" />
<mail-template name='task-assign'>
<actors>#{taskInstance.actorId}</actors>
<subject>Task '#{taskInstance.name}'</subject>
<text><![CDATA[Hi,
Task '#{taskInstance.name}' has been assigned to you.
Go for it: #{BaseTaskListURL}#{taskInstance.id}
Thanks.
---powered by JBoss jBPM---]]></text>
</mail-template>
<mail-template name='task-reminder'>
<actors>#{taskInstance.actorId}</actors>
<subject>Task '#{taskInstance.name}' !</subject>
<text><![CDATA[Hey,
Don't forget about #{BaseTaskListURL}#{taskInstance.id}
Get going !
---powered by JBoss jBPM---]]></text>
</mail-template>
</mail-templates>
この例 (BaseT askListURL) でわかるように、式で利用可能なメールテンプレートで追加の変数を定義で
きます。
テンプレートを含むファイルは、以下のようにjbpm.cfg.xmlで設定する必要があります。
<jbpm-configuration>
<string name="resource.mail.templates" value="jbpm.mail.templates.xml" />
</jbpm-configuration>
14.5. メ ー ル サ ー バ ー の 設 定
メールサーバーを設定する最も簡単な方法は、以下のようにjbpm.cfg.xmlでプロパ
ティjbpm .m ail.sm tp.hostを使用することです。
<jbpm-configuration>
<string name="jbpm.mail.smtp.host" value="localhost" />
</jbpm-configuration>
Alternatively, when more properties need to be specified, a resource reference to a properties file can be
given with the key '' like this:
<jbpm-configuration>
<string name='resource.mail.properties' value='jbpm.mail.properties' />
</jbpm-configuration>
14.6. 差 出 人 ア ド レ ス の 設 定
T he default value for the From address used in jPDL mails is jbpm @ noreply. T he from address of
mails can be configured in the jBPM configuration file jbpm.xfg.xml with key 'jbpm.mail.from.address' like
this:
111
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
<jbpm-configuration>
<string name='jbpm.mail.from.address' value='[email protected]' />
</jbpm-configuration>
14.7. メ ー ル サ ポ ー ト の カ ス タ マ イ ズ
All the mail support in jBPM is centralized in one class: org.jbpm .m ail.Mail T his is an
ActionHandler implementation. Whenever an mail is specified in the process xml, this will result in a
delegation to the mail class. It is possible to inherit from the Mail class and customize certain behavior
for your particular needs. T o configure your class to be used for mail delegations, specify a
'jbpm.mail.class.name' configuration string in the jbpm.cfg.xml like this:
<jbpm-configuration>
<string name='jbpm.mail.class.name'
value='com.your.specific.CustomMail' />
</jbpm-configuration>
カスタマイズされたメールクラスは解析中に読み取られ、アクションは設定された(またはデフォルトの)
メールクラス名を参照するプロセスで設定されます。したがって、プロパティを変更した場合でも、すで
にデプロイされたすべてのプロセスは引き続き古いメールクラス名を参照します。ただし、これは、jbpm
データベースに対する単純な更新ステートメントで簡単に更新できます。
14.8. メ ー ル サ ー バ ー
インストールが容易なメールサーバーを必要な場合は、JBossMail Server または Apache James をご検
討ください。
112
第15章 ロギング
第 15章 ロギング
ロギングの目的は、プロセス実行の履歴の追跡です。プロセス実行のランタイムデータが変更されると、
すべての差分はログに出力されます。
プロセスロギングは、この章で扱いますが、ソフトウェアロギングと混同しないことです。 ソフトウェア
ロギングは、ソフトウェアプログラムの実行を追跡します (一般的にデバッグ目的)。 プロセスロギング
は、プロセスインスタンスの実行の追跡をします。
プロセスロギング情報の利用は、様々なユースケースがあります。 最も明確なのは、プロセス実行の関係
者によるプロセス履歴のコンサルティングです。
他の使用ケースとして、ビジネスアクティビティモニタリング(BAM) があります。 BAMは、ビジネスプロ
セスについての役に立つ統計的情報をみつけるために、 プロセス実行ログのクエリや分析を行います。
例えば、プロセスの各ステップで平均どれくらいの時間を費やしているか? プロセスのボトルネックはど
こかなどです。 この情報は、組織内で現実的なビジネスプロセス管理を実装するキーになります。実際の
ビジネスプロセス管理とは、 組織がどうプロセスを管理するか、どのように情報技術によってサポートさ
れるか、 かつ、その2つが、反復プロセス内で他のプロセスをどう向上することができるか、といったも
のです。
また他の使用ケースとしては、アンドゥ(undo)機能です。プロセスログはアンドゥの実装に利用できま
す。 ログは、ランタイム時の情報の差分を含んでいるため、ログはプロセスを前の状態に戻す為に逆順に
動作することができます。
15.1. ロ グ 生 成
ログは、プロセス実行中に、jBPMモジュールによって生成されます。 ユーザもプロセスログに情報を出
力できます。ログエントリは、 org.jbpm .logging.log.ProcessLog を継承したJavaオブジェクト
です。 プロセスログエントリは、LoggingInstance に追加されます。
LoggingInstanceは、ProcessInstanceの任意拡張です。
BPMは様々なログの種類を生成します: グラフ実行ログ、コンテキストログ、タスク管理ログです。 こ
れらログに含まれている情報についての、より詳細な説明については、javadocを参照してください。 継
承ツリーをたどって確認できるので、org.jbpm .logging.log.ProcessLog からはじめることをお
薦めします。
LoggingInstance は、すべてのログエントリを集めます。 プロセスインスタンスが保存されたと
き、LoggingInstance のすべてのログがデータベースに流されます。 ProcessInstance の logs
フィールドは、 各トランザクションでデータベースからログが取得されることをさけるために、
hibernate にマッピングされていません。 各 ProcessLog は、実行パス(T oken) の コンテキスト内に作
られます、 ゆえに、ProcessLog は、そのトークンを参照します。 T oken は、ProcessLog のイン
デックスのためのインデックスシーケンスジェネレータとしても役立ちます。 これはログの取り込みに重
要になります。 このようにして、 結果的なトランザクションで生成されるログは連続的なシーケンス番
号を持ちます。
プロセスログの追加を行う API メソッドは次のとおりです。
public class LoggingInstance extends ModuleInstance {
...
public void addLog(ProcessLog processLog) {...}
...
}
ロギング情報のUMLダイアグラムはこのようになります。
113
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
図 15.1 jBPM ロギング情報クラス図
Com positeLog は特別なログエントリです。 いくつかの子ログの親ログとして役立ち、ログに階層構造
をもてます。ログ挿入のAPIメソッドは次のとおりです。
public class LoggingInstance extends ModuleInstance {
...
public void startCompositeLog(CompositeLog compositeLog) {...}
public void endCompositeLog() {...}
...
}
Com positeLogs は、ログの階層構造が一貫性を保てるよう try-finally ブロックでいつも呼ばれる
べきです。 例えば、
startCompositeLog(new MyCompositeLog());
try {
...
} finally {
endCompositeLog();
}
15.2. ロ グ の 設 定
ログが重要でないデプロイメントの場合は、jbpm.cfg.xml設定ファイルのjbpm-contextセクションのロギン
グ行を削除してください。
<service name='logging'
factory='org.jbpm.logging.db.DbLoggingServiceFactory' />
ログをフィルタする場合は、DbLoggingServiceのサブクラスであるLoggingServiceのカスタム実装を記述
する必要があります。また、カスタムロギングServiceFactoryを作成し、factory属性で指定する必要があ
ります。
15.3. ロ グ 取 得
前の節で説明しましたが、LoggingInstanceをそのログへとたどることでは、 データベースからログを取
得することはできません。 その代わり、プロセスインスタンスのログは、データベースから検索できま
す。 LoggingSession は、この目的のために2つのメソッドを持っています。
最初のメソッドは、あるプロセスインスタンスのすべてのログを取得します。 これらのログは、Mapで
114
第15章 ロギング
トークンによってグルーピングされています。 その Mapは、プロセスインスタンスの全トークンを
ProcessLogのリストに関連付けます。 リストには、作成された順の ProcessLog を含みます。
public class LoggingSession {
...
public Map findLogsByProcessInstance(long processInstanceId) {...}
...
}
2つ目のメソッドは、指定されたT okenでログを取得します。 返されるリストには作成された順の
ProcessLogを含みます。
public class LoggingSession {
public List findLogsByToken(long tokenId) {...}
...
}
15.4. デ ー タ ベ ー ス ウ ェ ア ハ ウ シ ン グ
場合によっては、データウェアハウシングテクニックをjBPMプロセスログに適用したくなるかもしれませ
ん。 データウェアハウシングとは、様々な目的で利用できるよう、プロセスログを別のデータベースに作
成できるということです。
T here may be many reasons why you want to create a data warehouse with the process log information.
Sometimes it might be to offload heavy queries from the 'live' production database. In other situations it
might be to do some extensive analysis. Data warehousing even might be done on a modified database
schema which is optimized for its purpose.
この節では、jBPMのコンテキストでのデータウェアハウシングのテクニックだけ紹介したいと思います。
データウェアハウシングの目的はとても多様で、そのすべての要件をあつかう一般的なソリューションを
jBPMに含むことはできません。
115
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
第 16章 jBPM プロセス定義言語 (jPDL)
jPDLは、xmlスキーマと、すべてのプロセス定義に関係するファイルを プロセスアーカイブにパッケージ
するためのメカニズムを指定します。
16.1. プ ロ セ ス ア ー カ イ ブ
プロセスアーカイブはzipファイルです。 プロセスアーカイブの中心的なファイル
は、processdefinition.xm l です。 主な情報は、プロセスグラフです。
processdefinition.xm l は、アクションとタスクについての情報も含んでいます。 プロセスアーカ
イブには、クラス、タスクの UI フォームなど他のプロセス関連ファイルも含めることができます。
16.1.1. プロセスアーカイブのデプロイ
プロセスアーカイブのデプロイは、3つの方法で行うことが可能です: プロセスデザイナツール、antタ
スク、プログラム。
Deploying a process archive with the designer tool is supported in the starter's kit. Right click on the
process archive folder to find the "Deploy process archive" option. T he starter's kit server contains the
jBPM webapp, which has a servlet to upload process archives called ProcessUploadServlet. T his servlet
is capable of uploading process archives and deploying them to the default jBPM instance configured.
antタスクによるデプロイは以下のように行うことが可能です。
<target name="deploy.par">
<taskdef name="deploypar" classname="org.jbpm.ant.DeployProcessTask">
<classpath --make sure the jbpm-[version].jar is in this classpath--/>
</taskdef>
<deploypar par="build/myprocess.par" />
</target>
一度に多くのプロセスアーカイブをデプロイするには、 ネストされた fileset 要素を使用します。 ファイ
ル属性自体はオプションです。 ant タスクの他の属性は以下のとおりです。
jbpmcfg
オプションです。 デフォルト値は、 jbpm .cfg.xm l です。 JBPM 設定ファイルでは、 データ
ベースおよびマッピングファイルの JDBC 接続プロパティを含む Hibernate 設定ファイルの場所
を指定できます (デフォルト値は hibernate.cfg.xm l)。
properties
オプションです。 hibernate.cfg.xm l にあるすべての Hibernate プロパティを上書きできま
す。
createschema
true に設定される場合は、 プロセスがデプロイされる前に jBPM データベーススキーマが作成さ
れます。
プロセスアーカイブは、org.jbpm .jpdl.par.ProcessArchiveDeployer クラスを使って、プログ
ラムでもデプロイできます。
16.1.2. プロセスバージョニング
116
第16章 jBPM プロセス定義言語 (jPD L)
プロセス定義がデプロイされ、多くの実行がまだ終了しておらず、デプロイしたいプロセス定義の新しい
バージョンがある場合はどうなりますか?
プロセスインスタンスは常に起動されたプロセス定義に対して実行します。ただし、jBPM では同じ名前
の複数のプロセス定義をデータベースで共存させることができます。したがって通常、プロセスインスタ
ンスは、処理時点で最新の有効なバージョンで開始して、その全生存期間のあいだは同じプロセス定義で
実行し続けます。 より新しいバージョンがデプロイされると、 古いプロセスインスタンスが古いバー
ジョンのプロセス定義で実行され続けているのと並行して、 新しく作成されたインスタンスは最新のバー
ジョンで開始されます。
プロセスに Java クラスの参照が含まれる場合、 Java クラスは、 2 つの方法で jBPM ランタイム環境で利
用できます (これらのクラスが jBPM クラスローダで可視できるようにする)。 これは、 通常 jbpm [version].jar の隣にある .jar ファイルに委譲クラスを含めることができることを意味します。 こ
の場合、 すべてのプロセス定義が同じクラスファイルを参照します。 また、 Java クラスはプロセスアー
カイブにも含めることができます。 プロセスアーカイブに委譲クラスを含めると (jbpm クラスローダから
は可視できません)、 jBPM はプロセス定義内でこれらのクラスをバージョン管理します。 プロセスのク
ラスロードの詳細については、 「委譲」 を参照してください。
プロセスアーカイブがデプロイされると、jBPMデータベースにプロセス定義を作成します。 プロセス定
義はプロセス定義名を基本にバージョニングされます。 名前がついたプロセスアーカイブがデプロイされ
ると、デプロイヤはバージョン番号を割り当てます。 この番号を割り当てるには、デプロイヤは同名のプ
ロセス定義の最も高いバージョン番号をルックアップして1を加えます。 名前のないプロセス定義は、
バージョン番号は、いつも-1です。
16.1.3. デプロイ済プロセス定義の変更
デプロイされた後のプロセス定義の変更をjBPMデータベースに反映させるには、 たくさんの落とし穴の
可能性があります。それゆえに、これは薦められません。
実際にプロセス定義にすることができる様々の可能な変更があります。 それら、いくつかのプロセス定義
は、無害ですが、他のいくつかは、 期待、または望んでいるものからは、はるかに遠いものがあります。
したがって、このアプローチではなく、新規定義へのプロセスインスタンスの移行を考慮して下さい
(「プロセスインスタンスのマイグレーティング」 を参照)。
考慮する場合、いくつかポイントがあります:
Use Hibernate's update: You can just load a process definition, change it and save it with the
Hibernate session. T he Hibernate session can be accessed with the method
Jbpm Context.getSession().
T he second level cache: A process definition would need to be removed from the second level cache
after you've updated an existing process definition. See also 「 2 次レベルキャッシュ」
16.1.4. プロセスインスタンスのマイグレーティング
他のプロセス定義の変更を行うアプローチは、 プロセス実行を新しいプロセス定義に変換することかもし
れません。 これが長い寿命をもつビジネスプロセスにとって些細でないことを考慮に入れてください。
現在は、この部分は独創的なサポートがまだ少ない実験場です。
As you know there is a clear distinction between process definition data, process instance data (the
runtime data) and the logging data. With this approach, you create a separate new process definition in
the jBPM database (by e.g. deploying a new version of the same process). T hen the runtime information
is converted to the new process definition. T his might involve a translation because tokens in the old
process might be pointing to nodes that have been removed in the new version. So only new data is
created in the database. But one execution of a process is spread over two process instance objects.
117
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
T his might become a bit tricky for the tools and statistics calculations. When resources permit us, we are
going to add support for this in the future. E.g. a pointer could be added from one process instance to it's
predecessor.
16.1.5. プロセス変換
A conversion class has been made available to assist you with converting your jBPM 2.0 process
archives into jBPM 3.0 compatible process archives. Create an output directory to hold the converted
process archives. Enter the following command line from the build directory of the jBPM 3.0 distribution:
java -jar converter.jar input directory output directory
input directory is the directory where your jBPM 2.0 process archives currently reside. output
directory is the new directory you have created for the newly converted process archives.
16.2. 委 譲
Delegation is the mechanism used to include the users' custom code in the execution of processes.
16.2.1. jBPMクラスローダ
jBPM クラスローダは jBPM クラスをロードするクラスローダです。 クラスパスにライブラリ jbpm 3.x.jar をもつクラスローダということです。 クラスを jBPM クラスローダから見えるようにするに
は、 それらを jar ファイルにいれて、 その jar ファイルを jbpm -3.x.jar と同じところにおきます。 例
えば、 web アプリケーションの場合には WEB-INF/lib フォルダの中です。
16.2.2. プロセスクラスローダ
委譲クラスは、それぞれのプロセス定義のプロセスクラスローダで読み込まれます。 プロセスクラスロー
ダは親としてjBPMクラスローダをもつクラスローダです。 プロセスクラスローダは、特定のプロセス定
義のすべてのクラスを追加します。 クラスをプロセスアーカイブの /class フォルダ内に置いてクラス
をプロセス定義に追加できます。 これはプロセス定義に追加したいクラスにバージョニングしたいときに
だけ役に立つことに注意してください。 もしバージョニングが必要でない場合には、jBPMクラスローダ
で有効にする、より多くの効率的な方法があります。
If the resource name doesn't start with a slash, resources are also loaded from the /classes directory
in the process archive. If you want to load resources outside of the classes directory, start with a double
slash ( // ). For example to load resource data.xm l which is located next to the processdefinition.xml
on the root of the process archive file, you can do class.getResource("//data.xm l") or
classLoader.getResourceAsStream ("//data.xm l") or any of those variants.
16.2.3. 委譲設定
委譲クラスは、プロセス実行内から呼ばれるユーザコードを含みます。 もっとも一般的なサンプルは、ア
クションです。 アクションの場合、ActionHandler インターフェイスの実装は、 プロセスのイベント
上で呼ばれるかもしれません。 委譲は、processdefinition.xm l で指定されます。 委譲を指定する
ときには、3つのデータを与えます。
1. クラス名(必須) : 移譲クラスの完全修飾クラス名
2. 設定タイプ (任意): 委譲オブジェクトのインスタンス化と設定方法を指定します。 デフォルトで
は、デフォルトコンストラクタが利用され、設定情報は無視されます。
3. 設定 (任意): 設定タイプに応じたフォーマットで記述された委譲オブジェクトの設定
次から、すべての設定タイプの説明です。
118
第16章 jBPM プロセス定義言語 (jPD L)
16.2.3.1. config-type フィールド
これはデフォルト設定タイプです。 config-type field は、 委譲クラスのオブジェクトを最初にイ
ンスタンス化し、 それから設定情報で指定 されているようにオブジェクトのフィールドに値をセットし
ます。 設定情報は xml で、 要素名がクラスのフィールド名に対応しなければいけません。 もし必要で可
能であれば、 要素の中身のテキストは、フィールドのタイプに変換されます。
サポートされる型変換
String doesn't need converting, of course. But it is trimmed.
int, long, float, double, ...などのプリミティブ型
およびプリミティブ型の基礎ラッパークラス
lists, sets and collections. In that case each element of the xml-content is considered as an element
of the collection and is parsed, recursively applying the conversions. If the type of the elements is
different from java.lang.String this can be indicated by specifying a type attribute with the fully
qualified type name. For example, following snippet will inject an ArrayList of Strings into field
'numbers':
<numbers>
<element>one</element>
<element>two</element>
<element>three</element>
</numbers>
T he text in the elements can be converted to any object that has a String constructor. T o use
another type than String, specify the elem ent-type in the field element ('numbers' in this case).
Here's another example of a map:
<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>
Map の場合、field-element の各要素には、1つの子要素 key と1つの子要素 value が必要です。key
と要素は、変換ルールを利用して再帰的にパースされます。 ちょうど collections と同じよう
に、type 属性が指定されていなければ java.lang.String への変換が想定されます。
org.dom4j.Element
その他のタイプのために、String コンストラクタが利用されます
次のクラスがサンプルになります。
public class MyAction implements ActionHandler {
// access specifiers can be private, default, protected or public
private String city;
Integer rounds;
...
}
これは、有効な設定です。
119
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
...
<action class="org.test.MyAction">
<city>Atlanta</city>
<rounds>5</rounds>
</action>
...
16.2.3.2. config-type Bean
config-type field と同様ですが、 直接フィールドにセットするのではなく、プロパティはセッタメ
ソッド経由でセットされます。 同じ変換が適用されます。
16.2.3.3. config-type コンストラクタ
インスタンシエータは委譲のXML要素の内容を完全に取得し、 テキストとして、委譲クラスのコンストラ
クタに渡します。
16.2.3.4 . config-type configuration-property
最初に、デフォルトコンストラクタが利用され、 インスタンシエータは委譲のxml要素の内容を完全に取
得し、 テキストとして、void configure(String) メソッドに渡します (jBPM 2 と同様)。
16.3. 式
For some of the delegations, there is support for a JSP/JSF EL like expression language. In actions,
assignments and decision conditions, you can write an expression like e.g.
expression="#{m yVar.handler[assignm ents].assign}"
式言語の基本は、 J2EEチュートリアル にあります。
jPDL式言語は、JSF式言語に似ています。 それは、jPDL ELはJSP ELに基づいていますが、 #{...} を利
用し、メソッドバインディングのサポートを含みます。
コンテキストによりますが、プロセス変数、もしくはタスクインスタンス変数は、 次の暗黙オブジェクト
と共に、開始変数として使うことができます。
taskInstance (org.jbpm.taskmgmt.exe.T askInstance)
processInstance (org.jbpm.graph.exe.ProcessInstance)
processDefinition (org.jbpm.graph.def.ProcessDefinition)
token (org.jbpm.graph.exe.T oken)
taskMgmtInstance (org.jbpm.taskmgmt.exe.T askMgmtInstance)
contextInstance (org.jbpm.context.exe.ContextInstance)
T his feature becomes really powerful in a JBoss SEAM environment. Because of the integration between
jBPM and JBoss SEAM, all of your backed beans, EJB's and other one-kind-of-stuff becomes
available right inside of your process definition.
16.4. jPDL XML ス キ ー マ
jPDLスキーマはプロセスアーカイブにある processdefinition.xm l で利用されるスキーマです。
16.4.1. バリデーション
jPDL の XML ドキュメントをパースするとき、 次の2つの条件が当てはまったとき、jBPM は jPDL スキー
マで XML ドキュメントを検証します。 最初に、スキーマがこのように XML ドキュメントで参照されてい
120
第16章 jBPM プロセス定義言語 (jPD L)
ること。
<process-definition xmlns="urn:jbpm.org:jpdl-3.2">
...
</process-definition>
2つ目に、Xerxes パーザがクラスパス上にあること
jPDLスキーマは${jbpm .hom e}/src/java.jbpm /org/jbpm /jpdl/xm l/jpdl3.2.xsdか、http://jbpm.org/jpdl-3.2.xsdにあります。
16.4.2. process-definition
121
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
表 16.1 プロセス定義スキーマ
Name
T ype
Multiplicit
y
Description
name
attribute
任意
プロセス名
element
[0..*]
プロセスで利用されるスイムレーン。スイムレー
ンはプロセス役割を表してタスク割り当てで利用
されます。
element
[0..1]
プロセスの開始状態。 開始状態のないプロセスは
有効ですが、実行することができないことに注意
してください。
element
[0..*]
アクションなどで使用できるグローバルに定義さ
れたタスク
element
[0..*]
このプロセス定義でスローされた移譲クラスに
よってスローされたすべての例外に適用される例
外ハンドラのリスト
element
[0..*]
プロセス定義のノード。ノードのないプロセスは
有効ですが、実行することができないことに注意
してください。
element
[0..*]
アクションのコンテナとして機能するプロセスイ
ベント
element
[0..*]
イベントと遷移から参照できるグローバルに定義
されたアクション。参照するにはこれらのアク
ションは名前を指定する必要があることに注意し
てください。
swimlane
[a]
start-state
[b ]
task [c ]
exception-handler
{end-state
[e] |state [f] |node
-node
[d ]
[g ] |task
[h] |process-
state
[i] |super-
state
[j] |fork [k] |join [l] |de
cision
[m] }
event [n]
{action
[o ] |script [p ] |crea
te-timer
timer
[q ] |cancel-
[r] }
[a] 「スイムレーン」.
[b ] 「s tart-s tate」.
[c ] 「タスク」.
[d ] 「exc ep tio n-hand ler」.
[e] 「end -s tate」.
[f] 「s tate」.
[g ] 「no d e」.
[h] 「tas k-no d e」.
[i] 「p ro c es s -s tate」.
[j] 「s up er-s tate」.
[k] 「fo rk」.
[l] 「jo in」.
[m] 「d ec is io n」.
[n] 「event」.
[o ] 「 アクション」.
[p ] 「s c rip t」.
[q ] 「c reate-timer」.
[r] 「c anc el-timer」.
16.4.3. node
122
第16章 jBPM プロセス定義言語 (jPD L)
表 16.2 Node スキーマ
Name
{action
[a] |script [b ] |crea
te-timer
timer
T ype
Multiplicit
y
Description
element
1
このノードの動作を表すカスタムアクション
[c ] |cancel-
[d ] }
common node
elements [e]
「一般的なノード要素」 を参照
[a] 「 アクション」.
[b ] 「s c rip t」.
[c ] 「c reate-timer」.
[d ] 「c anc el-timer」.
[e] 「一般的なノード要素」.
16.4.4. 一般的なノード要素
表 16.3 共通ノードスキーマ
Name
T ype
Multiplicit
y
Description
name
attribute
required
ノードの名前
async
attribute
{ true |
false },
falseがデ
フォルト値
true に設定されている場合、 このノードは非同期
で実行されます。 「 非同期続行」 も参照してく
ださい。
element
[0..*]
退場遷移。ノードを退場する遷移はそれぞれ一意
の明確な名前を持たなければいけません。 退場遷
移の内で最大のものは、無名でも許可されます。
指定されている遷移の最初のものは、デフォルト
遷移と呼ばれます。 デフォルト遷移は、遷移名を
指定せずにノードを退場する時に採り入れられま
す。
element
[0..*]
サポートされているイベントタイプ: {nodeenter|node-leave}
element
[0..*]
プロセスノードでスローされた移譲クラスによっ
てスローされたすべての例外に適用される例外ハ
ンドラのリスト
element
[0..*]
このノードでの実行の時間を監視するタイマーを
指定します。
transition
[a]
event [b ]
exception-handler
timer
[c ]
[d ]
[a] 「trans itio n」.
[b ] 「event」.
[c ] 「exc ep tio n-hand ler」.
[d ] 「timer」.
16.4.5. start-state
123
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
表 16.4 開始状態スキーマ
Name
T ype
Multiplicit
y
Description
name
attribute
任意
ノードの名前
task [a]
element
[0..1]
このプロセスに対して新しいインスタンスを起動
するまたはプロセスイニシエータを取得するタス
ク。「開始タスクのスイムレーン」 を参照
event [b ]
element
[0..*]
サポートされているイベントタイプ: {node-leave}
element
[0..*]
退場遷移。ノードを退場する各遷移は一意の名前
を持つ必要があります。
element
[0..*]
プロセスノードでスローされた移譲クラスによっ
てスローされたすべての例外に適用される例外ハ
ンドラのリスト
Name
T ype
Multiplicit
y
Description
name
attribute
required
終了状態の名前
event [a]
element
[0..*]
サポートされているイベントタイプ: {node-enter}
element
[0..*]
プロセスノードでスローされた移譲クラスによっ
てスローされたすべての例外に適用される例外ハ
ンドラのリスト
T ype
Multiplicit
y
Description
transition
[c ]
exception-handler
[d ]
[a] 「タスク」.
[b ] 「event」.
[c ] 「trans itio n」.
[d ] 「exc ep tio n-hand ler」.
16.4.6. end-state
表 16.5 終了状態スキーマ
exception-handler
[b ]
[a] 「event」.
[b ] 「exc ep tio n-hand ler」.
16.4.7. state
表 16.6 状態スキーマ
Name
common node
elements [a]
[a] 「一般的なノード要素」.
16.4.8. task-node
124
「一般的なノード要素」 を参照
第16章 jBPM プロセス定義言語 (jPD L)
表 16.7 タスクノードスキーマ
Name
T ype
Multiplicit
y
Description
signal
attribute
任意
{unsynchronized|never|first|first-wait|last|lastwait}、デフォルト値はlastです。signalはプロセ
ス実行継続のタスク完了の影響を指定します。
create-tasks
attribute
任意
{yes|no|true|false}、デフォルト値はtrueです。
ランタイム時に作成する必要があるタスクを決定
しなければならない場合は、falseに設定できま
す。この場合は、アクションをnode-enterに追
加し、アクションにタスクを作成して、createtasksをfalseに設定します。
end-tasks
attribute
任意
{yes|no|true|false}、デフォルト値は、falseで
す。 remove-tasksがtrueにセットされたと
き、node-leave上では、オープンなタスクすべ
ては終了します。
task [a]
element
[0..*]
このタスクノードに到着したときに、作られるべ
きタスク
common node
elements [b ]
「一般的なノード要素」 を参照
[a] 「タスク」.
[b ] 「一般的なノード要素」.
16.4.9. process-state
表 16.8 プロセス状態スキーマ
Name
T ype
Multiplicit
y
Description
binding
attribute
任意
サブプロセスが解決された時刻を定義します。
{late|*}がデフォルトで解決deploytime に設定され
ます。
element
1
このノードに関連付けられたサブプロセス
element
[0..*]
データを起動時にスーパープロセスからサブプロ
セスにどのようにコピーするかとデータをサブプ
ロセスの完了時にサブプロセスからスーパープロ
セスにどのようにコピーするかを指定します。
sub-process
variable
[a]
[b ]
common node
elements [c ]
「一般的なノード要素」 を参照
[a] 「 s ub -p ro c es s 」.
[b ] 「variab le」.
[c ] 「一般的なノード要素」.
16.4.10. super-state
125
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
表 16.9 親状態 (superstate) スキーマ
Name
{endstate [a] |state
T ype
Multiplicit
y
Description
element
[0..*]
superstate のノード。superstate はネスト化でき
ます。
[b ] |node [c
] |task-
node
[d ] |process-
state
[e] |super-
state
[f] |fork [g ] |join [h] |d
ecision
[i] }
common node
elements [j]
「一般的なノード要素」 を参照
[a] 「end -s tate」.
[b ] 「s tate」.
[c ] 「no d e」.
[d ] 「tas k-no d e」.
[e] 「p ro c es s -s tate」.
[f] 「s up er-s tate」.
[g ] 「fo rk」.
[h] 「jo in」.
[i] 「d ec is io n」.
[j] 「一般的なノード要素」.
16.4.11. fork
表 16.10 Fork スキーマ
Name
T ype
Multiplicit
y
common node
elements
Description
「一般的なノード要素」 を参照
[a]
[a] 「一般的なノード要素」.
16.4.12. join
表 16.11 Join スキーマ
Name
common node
elements [a]
[a] 「一般的なノード要素」.
16.4.13. decision
126
T ype
Multiplicit
y
Description
「一般的なノード要素」 を参照
第16章 jBPM プロセス定義言語 (jPD L)
表 16.12 Decision スキーマ
Name
handler
[a]
遷移の条件
T ype
Multiplicit
y
Description
element
either a
'handler'
element or
conditions
on the
transitions
should be
specified
org.jbpm .jpdl.Def.DecisionHandler 実
装の名前
決定を退場
する遷移の
属性または
要素テキス
ト
退場遷移。 ノードの各退場遷移は条件を持つこと
ができます。 決定では、 これらの条件を使用し
て条件が true であることを評価する最初の遷移を
検索します。 最初の遷移はブランチを表します。
したがって、 最初に条件を持つすべての遷移が評
価されます。 これらのいずれの条件も true でな
い場合は、 その遷移が取得されます。 条件を持
つ遷移が true に解決されない場合は、 デフォル
トの遷移 (最初の遷移) が取得されます。 「条
件」 を参照
common node
elements
「一般的なノード要素」 を参照
[b ]
[a] 「hand ler」.
[b ] 「一般的なノード要素」.
16.4.14. event
表 16.13 イベントスキーマ
Name
T ype
Multiplicit
y
Description
type
attribute
required
イベントタイプはイベントが置き換えられた要素
に対して相対的に表されます。
element
[0..*]
このイベントで実行すべきアクションのリスト
{action
[a] |script [b ] |crea
te-timer
timer
[c ] |cancel-
[d ] }
[a] 「 アクション」.
[b ] 「s c rip t」.
[c ] 「c reate-timer」.
[d ] 「c anc el-timer」.
16.4.15. transition
127
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
表 16.14 遷移スキーマ
Name
T ype
Multiplicit
y
Description
name
attribute
任意
遷移の名前。ノードを退場する各遷移は一意の名
前を持つ必要があることに注意してください。
to
attribute
required
宛先ノードの階層名。 階層名の詳細については、
「階層名(hierarchical name)」 を参照してくださ
い。
条件
属性または
要素テキス
ト
任意
ガード条件式 [a] これらの条件属性 (または、 子要
素) は決定ノードで使用したり、 実行時にトーク
ンで利用可能な遷移を計算するために使用したり
できます。
element
[0..*]
この遷移を取得時に実行するアクション。遷移の
アクションをイベントに配置する必要がないこと
に注意してください(遷移は1つだけだからで
す)。
element
[0..*]
プロセスノードでスローされた移譲クラスによっ
てスローされたすべての例外に適用される例外ハ
ンドラのリスト
{action
[b ] |script [c ] |crea
te-timer
timer
[d ] |cancel-
[e] }
exception-handler
[f]
[a] 「式」。
[b ] 「 アクション」.
[c ] 「s c rip t」.
[d ] 「c reate-timer」.
[e] 「c anc el-timer」.
[f] 「exc ep tio n-hand ler」.
16.4.16. アクション
128
第16章 jBPM プロセス定義言語 (jPD L)
表 16.15 アクションスキーマ
Name
T ype
Multiplicit
y
Description
name
attribute
任意
アクションの名前。アクションに名前が指定され
ている場合は、プロセス定義から名前を検索でき
ます。これは実行時アクションとアクションを一
度だけ宣言する場合に便利です。
class
attribute
参照名また
は式のいず
れか
org.jbpm .graph.def.ActionHandlerイン
ターフェースを実装するクラスの完全修飾クラス
名
ref-name
attribute
this または
class
参照されたアクションの名前。参照されたアク
ションが指定された場合はこのアクションの内容
が処理されません。
式
attribute
this、
class、refnameのい
づれか
メソッドを解決するjPDL式。 「式」 も参照して
ください。
accept-propagatedevents
attribute
任意
{yes|no|true|false}. Default is yes|true. If set to
false, the action will only be executed on events
that were fired on this action's element. for more
information, see 「イベント伝播」
config-type
attribute
任意
{field
[a] |bean [b ] |constructor [c ] |configuration-
property [d ] } action-object をどのように構築する
かと、 この要素の内容をその action-object の設
定情報としてどのように使用するかを指定しま
す。
async
attribute
{true|false}
'async="true" is only supported in action
when it is triggered in an event. T he default value
is false, which means that the action is
executed in the thread of the execution. If set to
true, a message will be sent to the command
executor and that component will execute the
action asynchronously in a separate transaction.
{content}
任意
アクションの内容は、 カスタムアクション実装の
設定情報として使用できます。 これにより、 再
利用可能な委譲クラスを作成できます。 委譲設定
の詳細については、 「委譲設定」 を参照してく
ださい。
[a] 「c o nfig -typ e フィールド」.
[b ] 「c o nfig -typ e Bean」.
[c ] 「c o nfig -typ e コンストラクタ」.
[d ] 「c o nfig -typ e c o nfig uratio n-p ro p erty」.
16.4.17. script
129
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
表 16.16 スクリプトスキーマ
Name
T ype
Multiplicit
y
Description
name
attribute
任意
script-actionの名前。アクションに名前が指定さ
れている場合は、名前をプロセス定義から検索で
きます。これは、実行時アクションの場合やアク
ションを一度だけ宣言する場合に便利です。
accept-propagatedevents
attribute
optional
[0..*]
{yes|no|true|false}. Default is yes|true. If set to
false, the action will only be executed on events
that were fired on this action's element. for more
information, see 「イベント伝播」
式 [a]
element
[0..1]
the beanshell script. If you don't specify
variable [b ] elements, you can write the
expression as the content of the script element
(omitting the expression element tag).
element
[0..*]
スクリプトの変数。in変数が指定されていない場
合は現在のトークンのすべての変数がスクリプト
評価にロードされます。スクリプト評価にロード
する変数の数を制限する場合は、in変数を使用し
ます。
T ype
Multiplicit
y
Description
variable
[c ]
[a] 「式」。
[b ] 「variab le」.
[c ] 「variab le」.
16.4.18. 式
表 16.17 表現スキーマ
Name
{content}
16.4.19. variable
130
Bean シェルスクリプト
第16章 jBPM プロセス定義言語 (jPD L)
表 16.18 変数スキーマ
Name
T ype
Multiplicit
y
Description
name
attribute
required
プロセス変数名
access
attribute
任意
デフォルト値はread,writeです。これはアクセ
ス指定子のコンマ区切りリストです。これまで使
用したアクセス指定子はread、write、およ
びrequiredだけです。
mapped-name
attribute
任意
デフォルトでは変数名に設定されます。変数名が
マップされた名前を指定します。mapped-name
の意味はこの要素が使用されるコンテキストに依
存します。スクリプトの場合はscript-variablenameになります。タスクコントローラの場合は
タスクフォームパラメータのラベルになり、
process-stateの場合はsub-processで使用された
変数名になります。
16.4.20. handler
表 16.19 ハンドラスキーマ
Name
T ype
Multiplicit
y
Description
式
attribute
this または
class
jPDL 式。 返された結果は toString() メソッドによ
り文字列に変換されます。 変換された文字列は退
場遷移のいずれかに一致します。 「式」 も参照
してください。
class
attribute
thisまたは
ref-name
org.jbpm .graph.node.DecisionHandler
インターフェースを実装するクラスの完全修飾ク
ラス名
config-type
attribute
任意
{field
[a] |bean [b ] |constructor [c ] |configuration-
property [d ] } action-object をどのように構築する
かと、 この要素の内容をその action-object の設
定情報としてどのように使用するかを指定しま
す。
{content}
任意
ハンドラの内容はカスタムハンドラ実装の設定情
報として使用できます。 これにより、再利用可能
な移譲クラスを作成できます。移譲設定の詳細に
ついては、 「委譲設定」を参照してください。
[a] 「c o nfig -typ e フィールド」.
[b ] 「c o nfig -typ e Bean」.
[c ] 「c o nfig -typ e コンストラクタ」.
[d ] 「c o nfig -typ e c o nfig uratio n-p ro p erty」.
16.4.21. timer
131
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
表 16.20 タイマースキーマ
Name
T ype
Multiplicit
y
Description
name
attribute
任意
タイマーの名前。名前を指定しない場合は、閉じ
るノードの名前が取得されます。各タイマーは一
意の名前を持つことに注意してください。
duedate
attribute
required
タイマーの作成からタイマーの実行までの時間
(営業時間で示すこともできます)。 構文について
は 「Duration (期間)」 を参照してください。
repeat
attribute
任意
{duration | 'yes' | 'true'}after a timer has been
executed on the duedate, 'repeat' optionally
specifies duration between repeating timer
executions until the node is left. If yes or true is
specified, the same duration as for the due date
is taken for the repeat. See 「Duration (期
間)」 for the syntax.
transition
attribute
任意
タイマーイベントが発生しアクションを実行した
後にタイマーが実行されたときに取得される
transition-name
cancel-event
attribute
任意
この属性はタスクのタイマーでのみ使用されま
す。タイマーをキャンセルするイベントを指定し
ます。デフォルトでは、task-end イベントです
が、たとえば task-assign または task-start
にセットできます。cancel-event 型は、属性
にカンマ区切りのリストで指定することで組み合
わせることができます。
element
[0..1]
このタイマーが起動したときに実行されるアク
ション
{action
[a] |script [b ] |crea
te-timer
timer
[c ] |cancel-
[d ] }
[a] 「 アクション」.
[b ] 「s c rip t」.
[c ] 「c reate-timer」.
[d ] 「c anc el-timer」.
16.4.22. create-timer
132
第16章 jBPM プロセス定義言語 (jPD L)
表 16.21 Create T imer スキーマ
Name
T ype
Multiplicit
y
Description
name
attribute
任意
タイマーの名前。この名前は cancel-timer アク
ションでタイマーをキャンセルするのに使用でき
ます。
duedate
attribute
required
タイマーの作成からタイマーの実行までの時間
(営業時間で示すこともできます)。 構文について
は 「Duration (期間)」 を参照してください。
repeat
attribute
任意
{duration | 'yes' | 'true'}after a timer has been
executed on the duedate, 'repeat' optionally
specifies duration between repeating timer
executions until the node is left. If yes of true is
specified, the same duration as for the due date
is taken for the repeat. See 「Duration (期
間)」 for the syntax.
transition
attribute
任意
タイマーイベントが発生し、アクションを実行し
た後にタイマーが実行されたときに取得する
transition-name
16.4.23. cancel-timer
表 16.22 Cancel T imer スキーマ
Name
T ype
Multiplicit
y
Description
name
attribute
任意
キャンセルされるタイマーの名前
16.4.24. タスク
133
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
表 16.23 タスクスキーマ
Name
T ype
Multiplicit
y
Description
name
attribute
任意
タスクの名前。名前が付けられたタスク
は、T askMgm tDefinitionによって参照および
検索できます。
blocking
attribute
任意
{yes|no|true|false}、デフォルトはfalseです。 も
しtrueにセットされた場合、タスクが終了してい
ない際にはノードを退場することはできません。
もしfalse (デフォルト) でセットされた場合、
トークンのシグナルは実行を続行し、ノードを退
場することができます。 blockingは普通、ユーザ
インターフェースによって 行われるものなのでデ
フォルトとしてfalseにしています。
signalling
attribute
任意
{yes|no|true|false}、デフォルト値は true です。
シグナリングが false に設定されている場合は、
このタスクはトークンの続行をトリガする能力を
持ちません。
duedate
attribute
任意
13章ビジネスカレンダ で説明された絶対または営
業時間で示された期間。
スイムレーン
attribute
任意
スイムレーン [a] の参照。 スイムレーンがタスク
で指定された場合、 割り当ては無視されます。
priority
attribute
任意
{highest, high, normal, low, lowest}のいずれか。
または、優先順位として整数を指定できます(最大
=1、最小=5)。
割り当て [b ]
element
任意
タスクが作成されたときにアクターにタスクを割
り当てる権限委譲 [c ] の説明。
event [d ]
exception-handler
timer
[f]
コントローラ [g ]
[a] 「スイムレーン」.
[b ] 「割り当て」
[c ] 「委譲」
[d ] 「event」.
134
[e]
element
[0..*]
サポートされているイベントタイプは{taskcreate|task-start|task-assign|task-end}。taskassignに対して特別に非永続化プロパ
ティpreviousActorIdをT askInstanceに追
加しました。
element
[0..*]
プロセスノードでスローされた移譲クラスによっ
てスローされたすべての例外に適用される例外ハ
ンドラのリスト
element
[0..*]
このタスクで実行の継続時間を監視するタイマー
を指定します。タスクタイマーに対して特別
にcancel-eventを指定できます。デフォルト
では、cancel-eventはtask-endです
が、task-assignやtask-startなどにカスタ
マイズできます。
element
[0..1]
プロセス変数をどのようにタスクフォームパラ
メータに変換するかを指定します。タスクフォー
ムパラメータはタスクフォームをユーザーにレン
ダリングするためにユーザーインターフェースに
よって使用されます。
第16章 jBPM プロセス定義言語 (jPD L)
[e] 「exc ep tio n-hand ler」.
[f] 「timer」.
[g ] 「コントローラ」.
16.4.25. スイムレーン
表 16.24 スイムレーンスキーマ
Name
T ype
Multiplicit
y
Description
name
attribute
required
スイムレーンの名前。スイムレーン
はT askMgm tDefinitionを使用して参照および
検索できます。
割り当て [a]
element
[1..1]
スイムレーンの割り当てを指定します。割り当て
は、このスイムレーンで最初のタスクインスタン
スが作成されたときに実行されます。
[a] 「割り当て」
16.4.26. 割り当て
135
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
表 16.25 割り当てスキーマ
Name
T ype
Multiplicit
y
Description
式
attribute
任意
歴史的な経緯から、 この属性式は jPDL 式 [a] を参
照しません。ただし、 jBPM ID コンポーネントの
割り当て式になります。 jBPM ID コンポーネント
式の記述方法の詳細については、 「割り当て式」
を参照してください。 この実装は jbpm ID コン
ポーネントの依存関係を持つことに注意してくだ
さい。
actor-id
attribute
任意
An actorId. Can be used in conjunction with
pooled-actors. T he actor-id is resolved as an
expression [b ] . So you can refer to a fixed actorId
like this actor-id="bobthebuilder". Or you
can refer to a property or method that returns a
String like this: actor-id="m yVar.actorId",
which will invoke the getActorId method on the
task instance variable "myVar".
プールアクター
attribute
任意
A comma separated list of actorIds. Can be used
in conjunction with actor-id. A fixed set of pooled
actors can be specified like this: pooledactors="chicagobulls,
pointersisters". T he pooled-actors will be
resolved as an expression [c ] . So you can also
refer to a property or method that has to return, a
String[], a Collection or a comma separated list of
pooled actors.
class
attribute
任意
org.jbpm .taskm gm t.def.Assignm entHan
dlerの実装の完全修飾クラス名
config-type
attribute
任意
{field
[d ] |bean [e] |constructor [f] |configuration-
property [g ] }. assignment-handler-object をどのよ
うに構築するかと、 その assignment-handlerobject の設定情報としてこの要素の内容をどのよ
うに使用するかを指定します。
{content}
[a] 「式」
[b ] 「式」.
[c ] 「式」.
[d ] 「c o nfig -typ e フィールド」.
[e] 「c o nfig -typ e Bean」.
[f] 「c o nfig -typ e コンストラクタ」.
[g ] 「c o nfig -typ e c o nfig uratio n-p ro p erty」.
16.4.27. コントローラ
136
任意
assignment-element の内容は
AssignmentHandler 実装の設定情報として使用で
きます。 これにより、 再利用可能な委譲クラス
を作成できます。 委譲設定の詳細については、
「委譲設定」 を参照してください。
第16章 jBPM プロセス定義言語 (jPD L)
表 16.26 コントローラスキーマ
Name
T ype
Multiplicit
y
Description
class
attribute
任意
org.jbpm .taskm gm t.def.T askControlle
rHandlerの実装の完全修飾クラス名
config-type
attribute
任意
{field
[a] |bean [b ] |constructor [c ] |configuration-
property [d ] }. assignment-handler-object をどのよ
うに構築するかと、 その assignment-handlerobject の設定情報としてこの要素の内容をどのよ
うに使用するかを指定します。
{content}
variable
[e]
element
どちらの場合もコントローラの内容は指定された
タスクコントローラハンドラの設定になります(ク
ラス属性が指定されている場合)。タスクコントー
ラハンドラが指定されていない場合は、内容を
variable要素のリストにしなければなりません。
[0..*]
タスクコントローラがクラス属性によって指定さ
れている場合、controller要素の内容は変数のリス
トである必要があります。
[a] 「c o nfig -typ e フィールド」.
[b ] 「c o nfig -typ e Bean」.
[c ] 「c o nfig -typ e コンストラクタ」.
[d ] 「c o nfig -typ e c o nfig uratio n-p ro p erty」.
[e] 「variab le」.
16.4.28. sub-process
表 16.27 サブプロセススキーマ
Name
T ype
Multiplicit
y
Description
name
attribute
required
sub-process の名前。 EL 式を使用できます
が、 String に解決する必要があります。
process-state の遅延バインドの場合に特に強力
です。
version
attribute
任意
sub-process のバージョン。 version が指定さ
れない場合、 jBPM は親の process-state をデプ
ロイするときに該当するプロセスの最新バージョ
ンを既知のものとして使用します。
binding
attribute
任意
Controls when the version of the sub-process
is determined. T he default behavior is to
determine the version when deploying the parent
process-state. If binding is defined as late
(binding="late") then it is determined when
the sub-process is invoked. If binding is set to
"late" and version is specified, then the value of
version will be ignored and the latest version will
be used.
16.4.29. 条件
137
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
表 16.28 条件スキーマ
Name
T ype
Multiplicit
y
Description
{content}
For
backwards
compatibilit
y, the
condition
can also
be entered
with the
'expressio
n' attribute,
but that
attribute is
deprecate
d since 3.2
required
条件要素の内容は、 ブール値を評価する jPDL
式 [a] です。決定により、 式を true に解決する
最初の遷移 (processdefinition.xml で決められた順
序を持つ) が使用されます。 どの条件も true に解
決されない場合は、 デフォルトの退場遷移 (最初
の遷移) が使用されます。
[a] 「式」.
16.4.30. exception-handler
表 16.29 例外ハンドラスキーマ
Name
T ype
Multiplicit
y
Description
exception-class
attribute
任意
この例外ハンドラに一致すべきJavaのスロー可能
なクラスの完全修飾名を指定します。この属性が
指定されない場合は、すべての例外
(java.lang.T hrowable)に一致します。
アクション [a]
element
[1..*]
この例外ハンドラによって例外が処理されるとき
に実行するアクションのリスト
[a] 「 アクション」.
138
第17章 セキュリティ
第 17章 セキュリティ
jBPMのセキュリティ機能は、まだアルファステージです。この章ではプラグイン可能な認証と認可につい
て説明します。また、フレームワークのどこが完了し、どこが未完了なのかについてもふれます。
17.1. TODO
フレームワークでは、プロセスが実行中に jbpm エンジンによって検証される 1セットのアクセス権を定
義する必要があります。現在は、独自のアクセス権をチェックできますが、まだアクセス権の jbpm デ
フォルトセットがありません。
ひとつだけ認証の実装が終了しています。他の認証実装も思い描けていますが、まだ実装されていませ
ん。認可は、任意で、認可機能はまだ実装されていません。また他にもいくつか認可の実装は思い描けて
いますが、まだうまくいっていません。
しかし、認証と認可の両方に関して、独自の認証と認可メカニズムをプラグインするためにフレームワー
クはあります。
17.2. 認 証
Authentication is the process of knowing on who's behalf the code is running. In case of jBPM this
information should be made available from the environment to jBPM. Cause jBPM is always executed in a
specific environment like a web application, an EJB, a swing application or some other environment, it is
always the surrounding environment that should perform authentication.
いくつかの状況では、jBPMは誰がそのコードを走らせているかを知らなければいけません。 例えば、プ
ロセスログに認証情報として、いつ、誰が、何をしたかを追加するといったことです。 他のサンプルは、
認証済アクターに基づくアクターの導出です。
誰がコードを実行しているか知らなければいけない状況では、中心的なメソッドの
org.jbpm .security.Authentication.getAuthenticatedActorId() を呼びます。そのメソッ
ドは、org.jbpm .security.authenticator.Authenticator の実装に委譲します。 authenticator
の実装を指定することで、jBPMがどう認証済アクターを取得するかを設定できます。
T he default authenticator is
org.jbpm .security.authenticator.Jbpm DefaultAuthenticator. T hat implementation will
maintain a T hreadLocal stack of authenticated actorId's. Authenticated blocks can be marked with the
methods Jbpm DefaultAuthenticator.pushAuthenticatedActorId(String) and
Jbpm DefaultAuthenticator.popAuthenticatedActorId(). Be sure to always put these
demarcations in a try-finally block. For the push and pop methods of this authenticator implementation,
there are convenience methods supplied on the base Authentication class. T he reason that the
JbpmDefaultAuthenticator maintains a stack of actorIds instead of just one actorId is simple: it allows the
jBPM code to distinct between code that is executed on behalf of the user and code that is executed on
behalf of the jbpm engine.
より詳細な情報はJavadocを参照してください。
17.3. 認 可
認可は、認証済ユーザがセキュアな操作を行うことを許可されているかどうか検証することです。
jBPMエンジンとユーザの記述するコードは、
org.jbpm .security.Authorization.checkPerm ission(Perm ission) メソッドで、操作が可
能なユーザか検証します。
139
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
Authrorization クラスは、その呼び出しを、設定可能な実装に委譲します。その異なる認証ストラテジ内
のプラグインのインターフェースは、 org.jbpm .security. authorizer.Authorizer です。
org.jbpm.security.authorizer パッケージでは、 いくつかの認証済みの実装の意図を表示するサンプルがあ
ります。 ほとんどが完全に実装されておらず、どれもテストされていません。
Also still to do is the definition of a set of jBPM permissions and the verification of those permissions by
the jBPM engine. An example could be verifying that the current authenticated user has sufficient
privileges to end a task by calling Authorization.checkPerm ission(new
T askPerm ission("end", Long.toString(id))) in the T askInstance.end() method.
14 0
第18章 Workflow の為の試し運転開発
第 18章 Workflow の為の試し運転開発
18.1. Workflow 用 の TDD の 紹 介
プロセス指向ソフトウェアの開発は、 他のソフトウェアの開発と何ら変わりはないので、プロセス定義は
簡単にテスト可能であるべきだと思います。 この章では、拡張することなく、作成したプロセス定義を単
体テストするために、簡素な JUnit を テストする方法を提示していきます。
開発サイクルは、できる限り短く保つべきです。 ソフトウェア変更については、すぐに検証可能であるべ
きです。 一時的なビルドステップを踏まずにできるのが好ましいと思います。 下記サンプルは、どのよ
うに一時的なステップを踏まずにjBPMプロセスを開発、テストするかをお見せします。
プロセス定義の単体テストのほとんどは、実行シナリオです。 各シナリオは、1つの JUnit テストメソッ
ドで実行され、外部トリガー(参照:シグナル) でプロセス実行に送り込んで、各シグナルの後にプロセスが
期待された状態にあるかどうかを検証します。
Let's look at an example of such a test. We take a simplified version of the auction process with the
following graphical representation:
図 18.1 オークションテストプロセス
Now, let's write a test that executes the main scenario:
14 1
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
public class AuctionTest extends TestCase {
// parse the process definition
static ProcessDefinition auctionProcess =
ProcessDefinition.parseParResource("org/jbpm/tdd/auction.par");
// get
static
static
static
the nodes for easy asserting
StartState start = auctionProcess.getStartState();
State auction = (State) auctionProcess.getNode("auction");
EndState end = (EndState) auctionProcess.getNode("end");
// the process instance
ProcessInstance processInstance;
// the main path of execution
Token token;
public void setUp() {
// create a new process instance for the given process definition
processInstance = new ProcessInstance(auctionProcess);
// the main path of execution is the root token
token = processInstance.getRootToken();
}
public void testMainScenario() {
// after process instance creation, the main path of
// execution is positioned in the start state.
assertSame(start, token.getNode());
token.signal();
// after the signal, the main path of execution has
// moved to the auction state
assertSame(auction, token.getNode());
token.signal();
// after the signal, the main path of execution has
// moved to the end state and the process has ended
assertSame(end, token.getNode());
assertTrue(processInstance.hasEnded());
}
}
18.2. XMLソ ー ス
Before you can start writing execution scenario's, you need a ProcessDefinition. T he easiest way
to get a ProcessDefinition object is by parsing XML. If you have code completion, type
ProcessDefinition.parse and activate code completion. T hen you get the various parsing
methods. T here are basically three ways to write XML that can be parsed to a ProcessDefinition
object:
18.2.1. プロセスアーカイブの構文解析
プロセスアーカイブとは、 processdefinition.xm l というプロセスのxmlファイルが含まれている
zipファイルです。 jBPMプロセスデザイナはプロセスアーカイブを読み書きします。例えば:
14 2
第18章 Workflow の為の試し運転開発
static ProcessDefinition auctionProcess =
ProcessDefinition.parseParResource("org/jbpm/tdd/auction.par");
18.2.2. XML ファイルの構文解析
他の状況では、processdefinition.xm l を手で書いて、 その後、ant スクリプトを利用して zip ファ
イルにパッケージングしたいかもしれません。 その場合は、JpdlXm lReader を利用します。
static ProcessDefinition auctionProcess =
ProcessDefinition.parseXmlResource("org/jbpm/tdd/auction.xml");
18.2.3. XML String の構文解析
単体テストでもっとも単純な選択は、簡素な String からインラインで XML を構文解析する方法です。
static ProcessDefinition auctionProcess =
ProcessDefinition.parseXmlString(
"<process-definition>" +
" <start-state name='start'>" +
"
<transition to='auction'/>" +
" </start-state>" +
" <state name='auction'>" +
"
<transition to='end'/>" +
" </state>" +
" <end-state name='end'/>" +
"</process-definition>");
14 3
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
第 19章 プラガブルアーキテクチャ
jBPM の機能はモジュールに分かれます。 各モジュールは、定義部分と実行(又はランタイム) 部分を持
ちます。 中心的なモジュールは、ProcessDefinition と ProcessInstance で構成されるグラフモ
ジュールです。 プロセス定義はグラフを含んでいます。そして、プロセスインスタンスはグラフの 1つの
実行を表します。 jBPM のほかのすべての機能は、オプションモジュールにグループ化されます。 オプ
ションモジュールは、コンテキスト(プロセス変数)、タスク管理、タイマなどの追加機能でグラフモ
ジュールを拡張できます。
図 19.1 プラガブルアーキテクチャ
jBPMのプラガブルアーキテクチャは、jBPMエンジンに独自な能力を追加する独自なメカニズムです。 カ
スタムプロセス定義情報は、ModuleDefinition 実装をプロセス定義に追加することによって追加でき
ます。 プロセスインスタンスが作成されるとき、 プロセス定義内の全ModuleDefinitionのインスタ
ンスを作成します。 ModuleDefinition は、ModuleInstance のファクトリとして利用されます。
プロセス定義の拡張を行うもっとも統合的な方法は、 プロセスアーカイブに情報を追加し
て、ProcessArchiveParser を実装することです。 ProcessArchiveParser はプロセスアーカイ
ブに追加された情報をパースし、 カスタムModuleDefinition を作成し、それ
をProcessDefinition に追加します。
public interface ProcessArchiveParser {
void writeToArchive(ProcessDefinition processDefinition, ProcessArchive
archive);
ProcessDefinition readFromArchive(ProcessArchive archive, ProcessDefinition
processDefinition);
}
その作業を行うのに、カスタム ModuleInstance は、 プロセス実行中、適切なイベントを通知しなけ
ればなりません。 カスタム ModuleDefinition は、これらプロセスイベントのコールバックハンドラ
として動作するイベントに対する ActionHandler 実装を追加するかもしれません。
また、カスタムモジュールは、カスタムインスタンスをプロセス実行にバインドするために、AOPを利用
14 4
第19章 プラガブルアーキテクチャ
するかもしれません。 JBossAOPは、成熟で、簡単に学習でき、JBossスタックの一部なので、この上記
作業において非常によく適合します。
14 5
JBoss Enterprise SOA Platform 4.3 JBPM リファレンスガイド
改訂履歴
改訂 1.2-10.4 02
Fri Oct 25 2013
Landmann Rüdiger [FAMILY
Given]
2012-07-18
T owns Anthony [FAMILY
Given]
Rebuild with Publican 4.0.0
改訂 1.2-10
Rebuild for Publican 3.0
改訂 1.2-0
Mon Aug 17 2009
Mison Darrin [FAMILY Given]
SOA 4.3.CP02 向けに更新
SOA-1436 - サブプロセス属性の詳細が明瞭化 (セクション 16.4.28)
SOA-1435 - プロセスアーカイブデプロイメントの詳細の更新 (セクション 16.1.1)
SOA-1434 - 非同期続行コンテンツの更新 (セクション 3.3.4, 12.1 および 16.4.16)
改訂 1.1-0
Fri Feb 27 2009
SOA 4.3.CP01 向けに更新
データベースアップグレードの章の更新
Mison Darrin [FAMILY Given]
改訂 1.0-0
Publican 形式に転換済み
Wulf Joshua [FAMILY Given]
14 6
T hu Sep 04 2008