ヘッダーをスキップ
Oracle Fusion Middleware Oracle SOA Suite開発者ガイド
11g リリース1(11.1.1)
B56238-01
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

13 BPELプロセスへのJavaおよびJava EEコードの組込み

この章では、JavaコードのセクションをSOAコンポジット・アプリケーションのBPELプロセス・サービス・コンポーネントに組み込む方法について説明します。

項目は次のとおりです。

13.1 BPELプロセスのJavaおよびJava EEコードの概要

この項では、JavaコードのセクションをBPELプロセスに組み込む方法について説明します。 この方法は、必要な関数を実行できるEnterprise JavaBeansのJavaコードが存在していて、BPELで最初から始めずにその既存のコードを使用する場合に特に役立ちます。

13.2 BPELプロセスへのJavaおよびJava EEコードの組込み

JavaおよびJava EEコードをBPELプロセスに組み込む方法は数種類あります。

13.2.1 JavaコードをSOAPサービスとしてラップする方法

Javaコードは、Simple Object Access Protocol(SOAP)サービスとしてラップできます。この方法では、JavaアプリケーションにBPEL互換のインタフェースが必要です。SOAPサービスとしてラップされたJavaアプリケーションは、他のWebサービスと同じように表示され、多様なアプリケーションで使用できます。また、SOAPラッパーの記述に使用できるツールもあります。

13.2.2 SOAPサービスとしてのJavaコードのラップに関する注意事項

SOAPサービスとしてラップされたJavaアプリケーションには、次の短所があります。

  • JavaとSOAP間での変換の性質により、パフォーマンスが低下する場合があります。

  • SOAPはトランザクションを本質的にはサポートしていないため、この方法ではアトミック・トランザクション性が失われます。つまり、複数の操作を、すべて実行するか、まったく実行しないという機能(ある銀行口座で借方記入し、別の口座で貸方記入するなど、両方のトランザクションを完了するか、どちらも完了しないかのどちらかなど)がありません。

13.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ファイルは、例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>

13.2.4 XML Facadeを使用してDOM操作を単純化する方法

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-2に例を示します。

例13-2 XML Facadeの追加

 <bpelx:exec name= ...
    <![CDATA
     ...
    Element element = ...
         (Element)getVariableData("input","payload","/loanApplication/"):
    //Create an XMLFacade for the Loan Application Document
    LoanApplication xmlLoanApp=
         LoanApplicationFactory.createFacade(element);
 ...

13.2.5 bpelx:exec組込みメソッドを使用する方法

表13-1に、スコープ変数、インスタンス・メタデータおよび監査証跡の読取りと更新に使用できる一連のbpelx:exec組込みメソッドを示します。

表13-1 bpelx:exec用の組込みメソッド

メソッド名 説明

Object lookup( String name )

JNDIアクセス

Locator getLocator( )

Oracle BPEL Process Managerのロケータ

long getInstanceId( )

各インスタンスに関連付けられている一意のID

String setTitle( String title ) / String getTitle()

このインスタンスのタイトル

String setStatus( String status ) / String getStatus()

このインスタンスのステータス

void setCompositeInstanceTitle(String title)

コンポジット・インスタンス・タイトルの設定

void setIndex( int i, String value ) / String getIndex( int i )

検索には6つの索引を使用可能

void setPriority( int priority ) / int getPriority()

優先度

void setCreator( String creator ) / String getCreator()

このインスタンスの開始ユーザー

void setCustomKey( String customKey ) / String getCustomKey()

2番目の主キー

void setMetadata( String metadata ) / String getMetadata ()

リストを生成するためのメタデータ

String getPreference( String key )

アクセス・プリファレンス

void addAuditTrailEntry(String message, Object detail)

監査証跡へのエントリの追加

void addAuditTrailEntry(Throwable t)

スーツケースに格納されたファイルへのアクセス

Object getVariableData(String name) throws BPELFault

スコープ内に格納された変数へのアクセスおよび更新

Object getVariableData(String name, String partOrQuery) throws BPELFault

変数のアクセスおよび更新

Object getVariableData(String name, String part, String query)

変数のアクセスおよび更新

void setVariableData(String name, Object value)

変数データの設定

void setVariableData(String name, String part, Object value)

変数データの設定

void setVariableData(String name, String part, String query, Object value)

変数データの設定


13.2.6 サービス・インタフェースにラップされたJavaコードを使用する方法

すべてのアプリケーションがサービス・インタフェースを公開するわけではありません。ビジネス・プロセスでカスタムJavaコードが必要なシナリオもあります。このシナリオの場合は、次の操作を実行できます。

  • カスタムJavaコードを記述します。

  • コードを埋め込むサービス・インタフェースを作成します。

  • SOAP経由で、JavaコードをWebサービスとして起動します。

たとえば、SOAP参照バインディング・コンポーネントでサービス・インタフェースを起動するSOAコンポジット・アプリケーションに、BPELプロセス・サービス・コンポーネントを作成すると仮定します。この例の場合、使用されるサービス・インタフェースは、Oracle Application Development Framework(ADF)Business Componentです。

このシナリオの高レベルな手順を次に示します。

サービス・インタフェースにラップされたJavaコードを使用する手順は、次のとおりです。

  1. Oracle JDeveloperでOracle ADF Business Componentサービスを作成します。

    この操作により、このサービスに対するWSDLファイルとXSDファイルが生成されます。

  2. BPELプロセス・サービス・コンポーネントを含むSOAアプリケーションを作成します。そのBPELプロセス・サービス・コンポーネントはコンポジット・サービスとして公開されている必要があります。これにより、BPELプロセスがインバウンドSOAPサービス・バインディング・コンポーネントに自動的に接続されます。

  3. Oracle ADF Business ComponentサービスWSDLをSOAコンポジット・アプリケーションにインポートします。

  4. Oracle ADF Business Componentサービス・インタフェースにバインディングするWebサービスを作成します。

  5. 次のタスクを実行するBPELプロセスを設計します。

    1. Oracle ADF Business ComponentサービスportTypeのパートナ・リンクを作成します。

    2. assignアクティビティを作成します。この例では、この手順により、データ(たとえば静的なXMLフラグメント)がOracle ADF Business Componentサービスに渡される変数にコピーされます。

    3. invokeアクティビティを作成し、手順5aで作成したパートナ・リンクに接続します。

  6. パートナ・リンク参照をコンポジット参照バインディング・コンポーネントに接続(ワイヤ)します。この参照は、Webサービス・バインディングを使用して、Oracle ADF Business Componentサービスをリモートでデプロイできるようにします。

  7. SOAアプリケーションをデプロイします。

  8. 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管理者ガイド』を参照してください。

13.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ディレクトリに追加されます。

13.3.1 カスタム・クラスおよびJARファイルの追加方法

bpelx:execにクラスが使用されている場合は、bpel-config.xmlbpelcClasspathにもJARを追加する必要があります。 また、JARはSOAコンポジット・アプリケーションによってロードされていることも必要です。

カスタム・クラスを追加する手順は、次のとおりです。

  1. classesディレクトリにクラスをコピーします。

  2. Oracle WebLogic Serverを再起動します。

カスタムJARを追加する手順は、次のとおりです。

  1. このディレクトリまたはそのサブディレクトリにJARファイルをコピーします。

  2. antを実行します。

  3. Oracle WebLogic Serverを再起動します。

13.4 Oracle JDeveloperのBPELプロセスでのJava埋込みの使用

Oracle JDeveloperでは、bpelx:execアクティビティを追加して、コード・スニペットをダイアログ・ボックスにコピーできます。


注意:

カスタム・クラスの場合は、埋込みJavaコードに必要なJARファイルをORACLE_HOME/domains/user_domain_name/config/soa-infra/configuration/bpel-config.xmlファイルのbpelcClasspath変数に設定する必要があります。 これにより、JARファイルがBPELローダーのクラスパスに追加されます。 複数のJARファイルを設定する場合は、UNIXではコロン(:)、Windowsではセミコロン(;)を使用して区切る必要があります。

13.4.1 Oracle JDeveloperのBPELプロセスでのJava埋込みの使用方法

Oracle JDeveloperのBPELプロセスでJava埋込みを使用する手順は、次のとおりです。

  1. 「コンポーネント・パレット」から、デザイナにJava Embeddingアクティビティをドラッグします。

  2. Java Embeddingアクティビティをダブルクリックして「Java Embedding」ダイアログを表示します。

  3. 「名前」フィールドに、名前を入力します。

  4. 「コード・スニペット」フィールドに、Javaコードを入力(またはカット・アンド・ペースト)します。

    図13-1 bpel:execコード例

    図13-1の説明は次にあります。
    「図13-1 bpel:execコード例」の説明


注意:

Java EmbeddingアクティビティにJavaコードを記述するかわりに、Javaコードを配置したJARファイルをクラスパスに設定し、Java Embeddingアクティビティ内からメソッドをコールすることもできます。

13.5 bpelx:execによるサービス・データ・オブジェクトの埋込み

サービス・データ・オブジェクト(SDO)コードは、bpelx:execタグを使用して.bpelファイルに埋め込むことができます。 例13-3の構文では、mytest.apps.SDOHelperがSDOを変更するJavaクラスです。

例13-3 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-4に、BPELファイルに埋め込まれているmodifySDO(o)およびprint(o)というJavaクラスの例を示します。

例13-4 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();
       }          }