この章では、JavaコードのセクションをSOAコンポジット・アプリケーションのBPELプロセス・サービス・コンポーネントに組み込む方法について説明します。
項目は次のとおりです。
この項では、JavaコードのセクションをBPELプロセスに組み込む方法について説明します。この方法は、必要な関数を実行できるEnterprise JavaBeansのJavaコードが存在していて、BPELで最初から始めずにその既存のコードを使用する場合に特に役立ちます。
JavaおよびJava EEコードをBPELプロセスに組み込む方法は数種類あります。
Simple Object Access Protocol(SOAP)サービスとしてラップする方法
bpelx:exec
タグを使用してBPELプロセスにJavaコード・スニペットを埋め込む方法
XML Facadeを使用してDOM操作を単純化する方法
bpelx:exec
組込みメソッドを使用する方法
サービス・インタフェースにラップされたJavaコードを使用する方法
Javaコードは、SOAPサービスとしてラップできます。この方法では、JavaアプリケーションにBPEL互換のインタフェースが必要です。SOAPサービスとしてラップされたJavaアプリケーションは、他のWebサービスと同じように表示され、多様なアプリケーションで使用できます。また、SOAPラッパーの記述に使用できるツールもあります。
SOAPサービスとしてラップされたJavaアプリケーションには、次の短所があります。
JavaとSOAP間での変換の性質により、パフォーマンスが低下する場合があります。
SOAPはトランザクションを本質的にはサポートしていないため、この方法ではアトミック・トランザクション性が失われます。つまり、複数の操作を、すべて実行するか、まったく実行しないという機能(ある銀行口座で借方記入し、別の口座で貸方記入するなど、両方のトランザクションを完了するか、どちらも完了しないかのどちらかなど)がありません。
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
ファイルは、例13-1に示すbpelx:exec
タグを使用して、invokeSessionBean
Java Beanを埋め込みます。
例13-1 bpelx:exec拡張要素
<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>
この章の例では主に、bpelx:exec
拡張要素を使用してJavaコード・スニペットを埋め込む方法に重点を置いています。BPEL仕様のバージョン2.0をサポートするBPELプロジェクトの場合、構文が多少異なります。bpelx:exec
拡張要素とJavaコードは<extensionActivity>
要素にラップされます。例13-2に詳細を示します。
例13-2 BPEL 2.0のbpelx:exec拡張要素
<extensionActivity> <bpelx:exec language="java"> <![CDATA[ java code ]]> </bpelx:exec> </extensionActivity>
Java EmbeddingアクティビティをOracle BPELデザイナのBPELプロセスにドラッグすると、<extensionActivity>
要素とbpelx:exec
タグが自動的に追加されます。
例13-3に、BPEL 2.0のimport構文を示します。
例13-3 BPEL 2.0のimport構文
<import location="class/package name" importType="http://schemas.oracle.com/bpel/extension/java"/>
例13-4に、BPELバージョン2.0をサポートするプロジェクトの2つのJava Embeddingアクティビティを含むBPELファイルを示します。
例13-4 バージョン2.0のBPELファイルのJava Embeddingアクティビティ
<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>
このアクティビティの使用については、第13.4項「Oracle JDeveloperのBPELプロセスでのJava Embeddingの使用」を参照してください。
DOM操作は、XML Facadeを使用して単純化できます。Oracle BPEL Process Managerには、XMLの他に、Java Architecture for XML Binding(JAXB)に類似した軽量のJavaオブジェクト・モデル(Facadeと呼ばれます)が用意されています。XML Facadeは、スキーマを備えたXML文書またはXML要素に対して、Java Beanのようなフロント・エンドを提供します。Facadeクラスを使用すると、Javaプログラム内でXML文書またはXML要素を簡単に操作できます。
XML Facadeを追加するには、.bpel
ファイルのbpelx:exec
文内でcreateFacade
メソッドを使用します。図13-5に例を示します。
表13-1に、スコープ変数、インスタンス・メタデータおよび監査証跡の読取りと更新に使用できる一連のbpelx:exec
組込みメソッドを示します。
表13-1 bpelx:exec用の組込みメソッド
メソッド名 | 説明 |
---|---|
|
JNDIアクセス |
|
各インスタンスに関連付けられている一意のID |
|
このインスタンスのタイトル |
|
このインスタンスのステータス |
|
コンポジット・インスタンス・タイトルの設定 |
|
検索には6つの索引を使用可能 |
|
このインスタンスの開始ユーザー |
|
2番目の主キー |
|
リストを生成するためのメタデータ |
|
アクセス・プリファレンス |
|
監査証跡へのエントリの追加 |
|
スーツケースに格納されたファイルへのアクセス |
|
スコープ内に格納された変数へのアクセスおよび更新 |
|
変数のアクセスおよび更新 |
|
変数のアクセスおよび更新 |
|
変数データの設定 |
|
変数データの設定 |
|
変数データの設定 |
すべてのアプリケーションがサービス・インタフェースを公開するわけではありません。ビジネス・プロセスでカスタム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 ADF Business Componentsの作成方法の詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』を参照してください。
SOAコンポジット・アプリケーションの起動方法の詳細は、『Oracle Fusion Middleware Oracle SOA SuiteおよびOracle Business Process Management Suite管理者ガイド』を参照してください。
SOAコンポジット・アプリケーションには、カスタム・クラスおよびJARファイルを追加できます。拡張クラスおよびJARをSOAコンポジット・アプリケーションに追加するためのSOA拡張ライブラリは、$ORACLE_HOME/soa/modules/oracle.soa.ext_11.1.1
ディレクトリにあります。Oracle JDeveloperでは、カスタム・クラスおよびJARはapplication_name
/project/sca-inf/lib
ディレクトリに追加されます。
bpelx:exec
にクラスが使用されている場合は、Oracle Enterprise Manager Fusion Middleware ControlのシステムMBeanブラウザで、BpelcClasspathプロパティを使用してJARも追加する必要があります。
JARをBpelcClasspathに追加する手順は、次のとおりです。
「SOAインフラストラクチャ」メニューから、「SOA管理」→「BPELプロパティ」の順に選択します。
「BPELサービス・エンジン・プロパティ」ページの下部で、「詳細BPEL構成プロパティ」をクリックします。
BpelcClasspathをクリックします。
「値」フィールドに、クラスパスを指定します。
「適用」をクリックします。
「戻る」をクリックします。
また、JARはSOAコンポジット・アプリケーションによってロードされていることも必要です。
カスタム・クラスを追加する手順は、次のとおりです。
classes
ディレクトリにクラスをコピーします。
Oracle WebLogic Serverを再起動します。
カスタムJARを追加する手順は、次のとおりです。
このディレクトリまたはそのサブディレクトリにJARファイルをコピーします。
ant
を実行します。
Oracle WebLogic Serverを再起動します。
Oracle JDeveloperでは、bpelx:exec
アクティビティを追加して、コード・スニペットをダイアログにコピーできます。
注意: カスタム・クラスの場合は、Oracle Enterprise Manager Fusion Middleware ControlのシステムMBeanブラウザで、BpelcClasspathプロパティに、埋込みJavaコードに必要なJARファイルを指定する必要があります。手順は、第13.3.1項「カスタム・クラスおよびJARファイルの追加方法」を参照してください。これにより、JARファイルがBPELローダーのクラスパスに追加されます。複数のJARファイルを設定する場合は、UNIXではコロン(: )、Windowsではセミコロン(; )を使用して区切る必要があります。 |
Oracle JDeveloperのBPELプロセスでJava埋込みを使用する手順は、次のとおりです。
「コンポーネント・パレット」から「Oracle Extensions」を展開します。
Java Embeddingアクティビティをデザイナにドラッグします。
Java Embeddingアクティビティをダブルクリックして「Java Embedding」ダイアログを表示します。
「名前」フィールドに、名前を入力します。
「コード・スニペット」フィールドにJavaコードを入力します(または切り取って貼り付けます)。図13-1に詳細を示します。
注意: Java EmbeddingアクティビティにJavaコードを記述するかわりに、Javaコードを配置したJARファイルをクラスパスに設定し、Java Embeddingアクティビティ内からメソッドをコールすることもできます。 |
Java Embeddingアクティビティでthread.sleep()
を使用するBPELプロセスを作成してデプロイすると、実行スレッドがブロックされ、そのスレッドに関連付けられているトランザクションをコミットできません。その結果、待機の終了後にのみBPELインスタンスが表示されますが、これは想定されている動作です。
かわりに、waitアクティビティを使用します。このアクティビティを使用すると、入力時にリソースが解放され、進行中のトランザクションのコミットと、データ・ストアへのBPELインスタンス・データのハイドレーションが可能になります。
サービス・データ・オブジェクト(SDO)コードは、bpelx:exec
タグを使用して.bpel
ファイルに埋め込むことができます。例13-6の構文では、mytest.apps.SDOHelper
がSDOを変更するJavaクラスです。
例13-6 bpelx:execタグを使用したSDOオブジェクトの埋込み
</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>
例13-7に、BPELファイルに埋め込まれているmodifySDO(o)
およびprint(o)
というJavaクラスの例を示します。
例13-7 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(); } }
Oracle BPEL Process Managerで使用されるクラスと同じ名前を持つカスタム接続マネージャ・クラスを実装する場合、カスタム・クラスがOracle BPEL Process Managerで使用されるクラスを上書きしないことを確認する必要があります。
たとえば、次のことを想定します。
BPELプロジェクトで埋込みJavaを使用しています。
接続マネージャ・カスタム・クラスは、BPEL接続マネージャ・クラスを上書きしています。
実行時にjava.lang.NoClassDefFoundError
が発生しています。
BPEL接続マネージャ・クラスが優先されるように構成する手順は、次のとおりです。
Oracle JDeveloperを起動します。
BPELプロジェクトを強調表示します。
「編集」メイン・メニューの「プロパティ」を選択します。
「ライブラリとクラスパス」を選択します。
「JAR/ディレクトリの追加」をクリックします。
カスタムJARファイルのある場所まで移動し、「選択」をクリックします。
クラスパスにカスタム接続マネージャのJARファイルが追加されます。
「OK」をクリックします。
BPELプロジェクトを再デプロイして再テストします。