14 BPELプロセスへのJavaおよびJava EEコードの組込み
bpelx:execを使用したサービス・データ・オブジェクト(SDO)の埋込み方法、およびBPELプロセスと共有されるカスタム接続マネージャ・クラスの実装方法について説明します。この章の内容は次のとおりです。
-
Oracle JDeveloperのBPELプロセスでのJava埋込みの使用
-
Oracle BPEL Process Managerとのクラスのカスタム実装の共有
Springコンポーネントを起動することもできます。詳細は、「Spring Frameworkを使用したSOAコンポジット・アプリケーションへの統合」を参照してください。
14.1 BPELプロセスのJavaおよびJava EEコードの概要
この項では、JavaコードのセクションをBPELプロセスに組み込む方法について説明します。この方法は、必要な関数を実行できるEnterprise JavaBeansのコードが存在していて、BPELで最初から始めずにその既存のコードを使用する場合に特に役立ちます。
14.2 BPELプロセスへのJavaおよびJava EEコードの組込み
JavaおよびJava EEコードをBPELプロセスに組み込む方法は数種類あります。
-
Simple Object Access Protocol (SOAP)サービスとしてラップする方法
-
bpelx:execタグを使用してBPELプロセスにJavaコード・スニペットを埋め込む方法 -
XML Facadeを使用してDOM操作を単純化する方法
-
bpelx:exec組込みメソッドを使用する方法 -
サービス・インタフェースにラップされたJavaコードを使用する方法
14.2.1 JavaコードをSOAPサービスとしてラップする方法
Javaコードは、SOAPサービスとしてラップできます。この方法では、JavaアプリケーションにBPEL互換のインタフェースが必要です。SOAPサービスとしてラップされたJavaアプリケーションは、他のWebサービスと同じように表示され、多様なアプリケーションで使用できます。また、SOAPラッパーの記述に使用できるツールもあります。
14.2.2 SOAPサービスとしてのJavaコードのラップに関する必知事項
SOAPサービスとしてラップされたJavaアプリケーションには、次の短所があります。
-
JavaとSOAP間での変換の性質により、パフォーマンスが低下する場合があります。
-
SOAPはトランザクションを本質的にはサポートしていないため、この方法ではアトミック・トランザクション性が失われます。つまり、複数の操作を、すべて実行するか、まったく実行しないという機能(ある銀行口座で借方記入し、別の口座で貸方記入するなど、両方のトランザクションを完了するか、どちらも完了しないかのどちらかなど)がありません。
14.2.3 bpelx:execタグを使用してBPELプロセスにJavaコード・スニペットを埋め込む方法
Javaコード・スニペットは、Java BPEL exec拡張要素bpelx:execを使用してBPELプロセスに直接埋め込むことができます。この方法の利点は、パフォーマンスに優れていることとトランザクション性が維持されることです。小さいコード・セグメントのみを組み込むことをお薦めします。BPELは、ビジネス・ロジックを実装から切り離します。プロセスの多数のJavaコードを削除すると、この切離しを維持できなくなります。Java埋込みは、ビジネス・コードではなく、短いユーティリティ系の操作を対象としています。ビジネス・ロジックは別の場所に配置し、配置したロジックをBPELからコールします。
サーバーは、bpelx:execアクティビティ内のJavaコード・スニペットをそのJava Transaction API (JTA)トランザクション・コンテキスト内で実行します。このBPELタグbpelx:execは、Java例外をBPELフォルトに変換し、BPELプロセスに追加します。Javaスニペットは、コールするセッションBeanとエンティティBeanに、そのJTAトランザクションを伝播できます。
たとえば、SessionBeanSample.bpelファイルは、次のコードに示すbpelx:execタグを使用して、invokeSessionBean Java Beanを埋め込みます。
<bpelx:exec name="invokeSessionBean" language="java" version="1.5">
<![CDATA[
try {
Object homeObj = lookup("ejb/session/CreditRating");
Class cls = Class.forName(
"com.otn.samples.sessionbean.CreditRatingServiceHome");
CreditRatingServiceHome ratingHome = (CreditRatingServiceHome)
PortableRemoteObject.narrow(homeObj,cls);
if (ratingHome == null) {
addAuditTrailEntry("Failed to lookup 'ejb.session.CreditRating'"
+ ". Ensure that the bean has been"
+ " successfully deployed");
return;
}
CreditRatingService ratingService = ratingHome.create();
// Retrieve ssn from scope
Element ssn =
(Element)getVariableData("input","payload","/ssn");
int rating = ratingService.getRating( ssn.getNodeValue() );
addAuditTrailEntry("Rating is: " + rating);
setVariableData("output", "payload",
"/tns:rating", new Integer(rating));
} catch (NamingException ne) {
addAuditTrailEntry(ne);
} catch (ClassNotFoundException cnfe) {
addAuditTrailEntry(cnfe);
} catch (CreateException ce) {
addAuditTrailEntry(ce);
} catch (RemoteException re) {
addAuditTrailEntry(re);
}
]]>
</bpelx:exec>14.2.4 BPEL 2.0プロセスにJavaコード・スニペットを埋め込む方法
この章の例では主に、bpelx:exec拡張要素を使用してJavaコード・スニペットを埋め込む方法に重点を置いています。BPEL仕様のバージョン2.0をサポートするBPELプロジェクトの場合、構文が多少異なります。bpelx:exec拡張要素とJavaコードは<extensionActivity>要素にラップされます。次の例に詳細を示します。
<extensionActivity> <bpelx:exec language="java"> <![CDATA[ java code ]]> </bpelx:exec> </extensionActivity>
Java EmbeddingアクティビティをOracle BPELデザイナのBPELプロセスにドラッグすると、<extensionActivity>要素とbpelx:execタグが自動的に追加されます。
次の例は、BPEL 2.0のimport構文を示しています。
<import location="class/package name" importType="http://schemas.oracle.com/bpel/extension/java"/>
ノート:
BPEL 2.0のimport構文は、次の構文を使用するBPEL 1.1の場合とは異なります。
<bpelx:exec import="class/package name"/>
次の例は、BPELバージョン2.0をサポートするプロジェクトの2つのJava Embeddingアクティビティを含むBPELファイルを示しています。
<process name="Test" targetNamespace="http://samples.otn.com/bpel2.0/ch10.9"
. . .
. . .
<import location="oracle.xml.parser.v2.XMLElement"
importType="http://schemas.oracle.com/bpel/extension/java"/>
. . .
<sequence>
. . .
<extensionActivity>
<bpelx:exec language="java">
XMLElement elem = (XMLElement) getVariableData("output", "payload");
elem.setTextContent("set by java exec");
</bpelx:exec>
</extensionActivity>
<extensionActivity>
<bpelx:exec language="java">
<![CDATA[XMLElement elem = (XMLElement) getVariableData("output",
"payload");
String t = elem.getTextContent();
elem.setTextContent(t + ", set by java exec 2");]]>
</bpelx:exec>
</extensionActivity>
. . .
</sequence>
</process>
このアクティビティの使用方法の詳細は、「BPELプロセスでのJava埋込みの使用」を参照してください。
14.2.5 XML Facadeを使用してDOM操作を単純化する方法
DOM操作は、XML Facadeを使用して単純化できます。Oracle BPEL Process ManagerとOracle Mediatorには、XMLの上部に、Facadeという軽量Java Architecture for XML Binding(JAXB)のようなJavaオブジェクト・モデルが用意されています。XML Facadeは、スキーマを持つXML文書またはXML要素に対して、Java Beanのようなフロント・エンドを提供します。Facadeクラスを使用すると、Javaプログラム内でXML文書またはXML要素を簡単に操作できます。
XML Facadeを追加するには、.bpelファイルのbpelx:exec文内でcreateFacadeメソッドを使用します。次に例を示します。
<bpelx:exec name= ...
<![CDATA
...
Element element = ...
(Element)getVariableData("input","payload","/loanApplication/"):
//Create an XMLFacade for the Loan Application Document
LoanApplication xmlLoanApp=
LoanApplicationFactory.createFacade(element);
...14.2.6 bpelx:exec組込みメソッドを使用する方法
表14-1に、スコープ変数、インスタンス・メタデータおよび監査証跡の読取りと更新に使用できる一連のbpelx:exec組込みメソッドを示します。
表14-1 bpelx:exec用の組込みメソッド
| メソッド名 | 説明 |
|---|---|
|
|
JNDIアクセス |
|
|
各インスタンスに関連付けられている一意のID |
|
|
このインスタンスのタイトル |
|
|
このインスタンスのステータス |
|
|
コンポジット・インスタンス・タイトルの設定 |
|
|
検索には6つの索引を使用可能 |
|
|
このインスタンスの開始ユーザー |
|
|
2番目の主キー |
|
|
リストを生成するためのメタデータ |
|
|
アクセス・プリファレンス |
|
|
監査証跡へのエントリの追加 |
|
|
アーカイブに格納されたファイルへのアクセス |
|
|
スコープ内に格納された変数へのアクセスおよび更新 |
|
|
変数のアクセスおよび更新 |
|
|
変数のアクセスおよび更新 |
|
|
変数データの設定 |
|
|
変数データの設定 |
|
|
変数データの設定 |
14.2.7 サービス・インタフェースにラップされたJavaコードを使用する方法
すべてのアプリケーションがサービス・インタフェースを公開するわけではありません。ビジネス・プロセスでカスタムJavaコードが必要なシナリオもあります。このシナリオの場合は、次の操作を実行できます。
-
カスタムJavaコードを記述します。
-
コードを埋め込むサービス・インタフェースを作成します。
-
SOAP経由で、JavaコードをWebサービスとして起動します。
たとえば、SOAP参照バインディング・コンポーネントでサービス・インタフェースを起動するSOAコンポジット・アプリケーションに、BPELプロセス・サービス・コンポーネントを作成すると仮定します。この例の場合、使用されるサービス・インタフェースは、Oracle Application Development Framework (ADF) Business Componentです。
このシナリオの高レベルな手順を次に示します。
サービス・インタフェースにラップされたJavaコードを使用するには:
-
Oracle JDeveloperでOracle ADF Business Componentサービスを作成します。
この操作により、このサービスに対するWSDLファイルとXSDファイルが生成されます。
-
BPELプロセス・サービス・コンポーネントを含むSOAコンポジット・アプリケーションを作成します。そのBPELプロセス・サービス・コンポーネントはコンポジット・サービスとして公開されている必要があります。これにより、BPELプロセスがインバウンドSOAPサービス・バインディング・コンポーネントに自動的に接続されます。
-
Oracle ADF Business ComponentサービスWSDLをSOAコンポジット・アプリケーションにインポートします。
-
Oracle ADF Business Componentサービス・インタフェースにバインディングするWebサービスを作成します。
-
次のタスクを実行するBPELプロセスを設計します。
-
パートナ・リンク参照をコンポジット参照バインディング・コンポーネントに接続(ワイヤ)します。この参照は、Webサービス・バインディングを使用して、Oracle ADF Business Componentサービスをリモートでデプロイできるようにします。
-
SOAコンポジット・アプリケーションをデプロイします。
-
Oracle Enterprise Manager Fusion Middleware Controlの「Webサービスのテスト」ページから、このSOAアプリケーションを起動します。詳細は、『Oracle SOA SuiteおよびOracle Business Process Management Suiteの管理』のビジネス・フローのテスト・インスタンスの起動に関する項を参照してください。
Oracle ADF Business Componentを作成する方法の詳細は、『Oracle Application Development FrameworkによるFusion Webアプリケーションの開発』を参照してください。
14.3 カスタム・クラスおよびJARファイルの追加
SOAコンポジット・アプリケーションには、カスタム・クラスおよびJARファイルを追加できます。拡張クラスおよびJARをSOAコンポジット・アプリケーションに追加するためのSOA拡張ライブラリは、$ORACLE_HOME/soa/modules/oracle.soa.ext_11.1.1ディレクトリにあります。Oracle JDeveloperでは、カスタム・クラスおよびJARはapplication_name/project/sca-inf/libディレクトリに追加されます。
14.3.1 カスタム・クラスおよびJARファイルの追加方法
bpelx:execにクラスが使用されている場合は、Oracle Enterprise Manager Fusion Middleware ControlのシステムMBeanブラウザで、BpelcClasspathプロパティを使用してJARも追加する必要があります。
14.4 Oracle JDeveloperのBPELプロセスでのJava埋込みの使用
Oracle JDeveloperでは、bpelx:execアクティビティを追加して、コード・スニペットをダイアログにコピーできます。
ノート:
カスタム・クラスの場合は、Oracle Enterprise Manager Fusion Middleware ControlのシステムMBeanブラウザで、BpelcClasspathプロパティに、埋込みJavaコードに必要なJARファイルを指定する必要があります。手順は、「カスタム・クラスおよびJARファイルの追加方法」を参照してください。これにより、JARファイルがBPELローダーのクラスパスに追加されます。複数のJARファイルを設定する場合は、UNIXではコロン(:)、Windowsではセミコロン(;)を使用して区切る必要があります。
14.4.1 Oracle JDeveloperのBPELプロセスでのJava埋込みの使用方法
Oracle JDeveloperのBPELプロセスでJava埋込みを使用するには:
ノート:
Java EmbeddingアクティビティにJavaコードを記述するかわりに、Javaコードを配置したJARファイルをクラスパスに設定し、Java Embeddingアクティビティ内からメソッドをコールすることもできます。
14.4.2 Java Embeddingアクティビティでのthread.sleep()の使用に関する必知事項
Java Embeddingアクティビティでthread.sleep()を使用するBPELプロセスを作成してデプロイすると、実行スレッドがブロックされ、そのスレッドに関連付けられているトランザクションをコミットできません。その結果、待機の終了後にのみBPELインスタンスが表示されますが、これは想定されている動作です。
かわりに、waitアクティビティを使用します。このアクティビティを使用すると、入力時にリソースが解放され、進行中のトランザクションのコミットと、データ・ストアへのBPELインスタンス・データのハイドレーションが可能になります。
14.5 bpelx:execによるサービス・データ・オブジェクトの埋込み
SDOコードは、bpelx:execタグを使用して.bpelファイルに埋め込むことができます。次の例の構文では、mytest.apps.SDOHelperがSDOを変更するJavaクラスです。
</bpelx:exec> <bpelx:exec name="ModifyInternalSDO" version="1.5" language="java"> <![CDATA[try{ Object o = getVariableData("VarSDO"); Object out = getVariableData("ExtSDO"); System.out.println("BPEL:Modify VarSDO... " + o + " ExtSDO: " + out); mytest.apps.SDOHelper.print(o); mytest.apps.SDOHelper.print(out); mytest.apps.SDOHelper.modifySDO(o); System.out.println("BPEL:After Modify VarSDO... " + o + " ExtSDO: " + out); mytest.apps.SDOHelper.print(o); mytest.apps.SDOHelper.print(out); }catch(Exception e) { e.printStackTrace(); }]]> </bpelx:exec>
次の例は、BPELファイルに埋め込まれているmodifySDO(o)およびprint(o)というJavaクラスの例を示しています。
public static void modifySDO(Object o){
if(o instanceof commonj.sdo.DataObject)
{
((DataObject)o).getChangeSummary().beginLogging();
SDOType type = (SDOType)((DataObject)o).getType();
HelperContext hCtx = type.getHelperContext();
List<DataObject> lines =
(List<DataObject>)((DataObject)o).get("line");
for (DataObject line: lines) {
line.set("eligibilityStatus", "Y");
}
} else {
System.out.println("SDOHelper.modifySDO(): " + o + " is not a
DataObject!");
}
}
. . .
. . .
public static void print(Object o) {
try{
if(o instanceof commonj.sdo.DataObject)
{
DataObject sdo = (commonj.sdo.DataObject)o;
SDOType type = (SDOType) sdo.getType();
HelperContext hCtx = type.getHelperContext();
System.out.println(hCtx.getXMLHelper().save(sdo, type.getURI(),
type.getName()));
} else {
System.out.println("SDOHelper.print(): Not a sdo " + o);
}
}catch(Exception e)
{
e.printStackTrace();
} } 14.6 Oracle BPEL Process Managerとのクラスのカスタム実装の共有
Oracle BPEL Process Managerで使用されるクラスと同じ名前を持つカスタム接続マネージャ・クラスを実装する場合、カスタム・クラスがOracle BPEL Process Managerで使用されるクラスをオーバーライドしないことを確認する必要があります。
たとえば、次のことを想定します。
-
BPELプロジェクトで埋込みJavaを使用しています。
-
接続マネージャ・カスタム・クラスは、BPEL接続マネージャ・クラスをオーバーライドしています。
-
実行時に
java.lang.NoClassDefFoundErrorが発生しています。
