Oracle Jolt

     前  次    新しいウィンドウで目次を開く     
ここから内容の開始

Jolt クラス ライブラリを使う

Oracle Jolt クラス ライブラリは、Oracle Tuxedo サービスにアクセスするための、開発者向けのオブジェクト指向の Java 言語クラス セットです。クラス ライブラリには、Jolt API を実装するクラス ファイルがあります。これらのクラスを使うと、アプリケーションを拡張してインターネットやイントラネットでトランザクション処理ができるようになります。Jolt クラス ライブラリを使用して、Java アプレットから Oracle Tuxedo サービスへのアクセスをカスタマイズすることもできます。

ここでは、以下の内容について説明します。

以降の節の情報を活用するには、Java 言語によるプログラミングおよびオブジェクト指向プログラミングに関する全般的な知識が必要です。この章で取り上げるプログラムの例はすべて Java コードで記述されています。

注意 : プログラムの例では、Jolt の機能を示す部分を抜粋して示しています。そのままコンパイルしたり、実行しないでください。これらのプログラム例を実際に実行するには、コードを追加する必要があります。

 


クラス ライブラリの機能の概要

Jolt クラス ライブラリには、クライアントサイドのアプリケーションやアプレット (独立した Java アプリケーションとして実行するか、または Java 対応の Web ブラウザで実行) を開発するための Oracle Tuxedo アプリケーション開発者向けのツールが用意されています。bea.jolt パッケージには Jolt クラス ライブラリが用意されています。Jolt クラス ライブラリを使用するには、クライアント プログラムやアプレットでこのパッケージをインポートする必要があります。bea.jolt パッケージをインポートする方法については、「Jolt のファンド転送の例 (SimXfer.java)」を参照してください。

Java アプリケーションと Java アプレット

ブラウザで実行する Java プログラムは「アプレット」と呼ばれます。アプレットとは、アプリケーションの一部として特定の機能を実行し、簡単にダウンロードできるサイズの小さいプログラムのことです。多くのブラウザでは、高度なセキュリティを実現するため、Java アプレットの機能に制限が設けられています。以下は、アプレットに対するいくつかの制限です。

Java アプレットの制限には、大抵の場合プログラミング上の対応策があります。ブラウザでサポートされるアプレットの機能またはアプレットの制限については、お使いのブラウザの Web サイト (www.netscape.com、www.microsoft.com など) や開発者用マニュアルを参照してください。また、Jolt リレーを使うと、ネットワーク接続に関するいくつかの制限を回避することができます。

一方、Java アプリケーションはブラウザ上では実行されず、上記のような制限を受けることはありません。たとえば、Java アプリケーションは、実行中のホスト マシン上で別のアプリケーションを起動できます。アプレットがユーザ インタフェースとしてブラウザや appletviewer のウィンドウ環境に依存するのに対し、Java アプリケーションでは独自のユーザ インタフェースを作成する必要があります。また、アプレットが可搬性のある小さいプログラムとして設計されるのに対し、Java アプリケーションは Java 以外の言語で作成されたプログラムとほとんど同じように操作することができます。Java アプリケーションと Java アプレットの最大の違いは、アプレットに対して設けられているブラウザでのセキュリティの制限およびプログラムの適応範囲です。

Jolt クラス ライブラリの特徴

Jolt クラス ライブラリには次の特徴があります。

エラーと例外処理

Jolt クラス ライブラリは、Jolt インタープリタのエラーおよび Oracle Tuxedo のエラーを例外として返します。「Jolt Class Library Reference」では、Jolt クラスと、各クラスのエラーや例外を一覧表示します。『Oracle Jolt API リファレンス』には、エラーと例外のクラス リファレンスが含まれています。

Jolt でのクライアント/サーバ関係

Oracle Jolt は、分散型のクライアント/サーバ環境で動作し、Java クライアントを Oracle Tuxedo をベースとするアプリケーションに接続します。

次の図は、Jolt プログラムと Jolt サーバの間のクライアント/サーバ関係を示しています。

図 5-1 Jolt でのクライアント/サーバ関係

図に示すように、Jolt サーバはネイティブな Oracle Tuxedo クライアントのプロキシとして動作し、ネイティブな Oracle Tuxedo クライアントで利用できる機能を実装します。Oracle Jolt サーバは、Oracle Jolt クライアントからのリクエストを受け取ると、Oracle Tuxedo ATMI インタフェースを介してこれらのリクエストを Oracle Tuxedo サービス要求にマッピングします。リクエストおよび関連付けられたパラメータは、メッセージ バッファにパッケージされ、ネットワーク経由で Oracle Jolt サーバに配信されます。Oracle Jolt サーバと Oracle Jolt アプレットの間のすべての通信は、Oracle Jolt 接続マネージャにより、Oracle Jolt トランザクション プロトコルを使用して処理されます。Oracle Jolt サーバは、メッセージからデータを取り出し、必要に応じてデータ変換 (数値形式や文字セットなど) を行ってから、メッセージで指定された適切なサービスを Oracle Tuxedo に要求します。

Oracle Tuxedo システムが受け取ったサービス要求は、ほかの Oracle Tuxedo のリクエストとまったく同じ方法で処理されます。結果は ATMI インタフェースを通して Oracle Jolt サーバに返され、そこで結果とエラー情報がメッセージにパッケージ化されると、Oracle Jolt のクライアント アプレットに送信されます。Oracle Jolt クライアントはメッセージの中身を様々な Oracle Jolt クライアント インタフェース オブジェクトにマップして、リクエストを完了します。

クライアントサイドでは、ユーザ プログラムにクライアント アプリケーション コードが含まれています。Jolt クラス ライブラリが提供する JoltSession と JoltTransaction がサービス要求を処理します。

次の表は、クライアントサイドから送信されるリクエストと、それに対する Jolt サーバサイドのアクションを簡単なプログラムの例で示したものです。

表 5-1 Jolt クライアント/サーバの相互作用
Jolt クライアント
Jolt サーバ
1
attr=new JoltSessionAttributes();
attr.setString(attr.APPADDRESS, “//myhost:8000”);
クライアントを Oracle Tuxedo 環境にバインドする。
2
session=new JoltSession(attr, username, userRole, userPassword, appPassword);
クライアントを Oracle Tuxedo にログオンさせる。
3
withdrawal=new JoltRemoteService( servname, session );
リポジトリ内のサービス属性を検索する。
4
withdrawal.addString(“accountnumber”, “123”);
withdrawal.addFloat(“amount”, (float) 100.00);
クライアントに変数を設定する (Jolt サーバ側の動作ではない)。
5
trans=new JoltTransaction( time-out, session);
新しい Tuxedo トランザクションを開始する。
6
withdrawal.call(trans);
Oracle Tuxedo サービスを実行する。
7
trans.commit() or trans.rollback();
トランザクションを完了またはロールバックする。
8
balance=withdrawal.getFloatDef(“balance,” (float) 0.0);
結果を取り出す (Jolt サーバ側の動作ではない)。
9
session.endSession();
クライアントを Oracle Tuxedo からログオフさせる。

Jolt クライアント/サーバの相互作用」をまとめると、次のようになります。

  1. JoltSessionAttributes クラスを使用してクライアントを Oracle Tuxedo 環境にバインドします。
  2. セッションを確立します。
  3. 変数を設定します。
  4. 必要なトランザクション処理を行います。
  5. クライアントを Oracle Tuxedo からログオフさせます。

上記のアクティビティは、Jolt クラス ライブラリのクラスによって処理されます。これらのクラスには、データの設定や消去を行ったり、リモート サービスのアクションを処理するメソッドが用意されています。Jolt クラス ライブラリの詳細については、「Jolt オブジェクト間の関係」を参照してください。

 


Jolt オブジェクト間の関係

次の図は、Jolt クラス ライブラリのクラスをインスタンス化したオブジェクトの関係を示しています。

図 5-2 Jolt オブジェクト間の関係

Jolt オブジェクト間の関係

Jolt クラスは、オブジェクトとしてさまざまな関係で相互作用します。上の図は、3 種類の基本的な関係を示しています。

 


Jolt クラス ライブラリの使い方

Jolt クラスを使用すると、ログオン/ログオフ、同期型のサービス呼び出し、トランザクションの開始、トランザクションのコミット、トランザクションのロールバックなどの基本的なトランザクション処理を実行できます。次の節では、これらの機能を実行するための Jolt クラスの使い方を説明します。

Jolt クラス ライブラリを使用して、マルチスレッド化されたアプリケーションを開発したり、Tuxedo 固有のバッファ型を定義したり、イベントや非請求メッセージのサブスクライブを実行することもできます。これらの機能については、後の節で説明します。

ログオン/ログオフ

クライアント アプリケーションには、トランザクション処理を行う前に Oracle Tuxedo 環境にログオンしておく必要があります。Jolt クラス ライブラリには、Oracle Tuxedo システムとの接続を確立するための JoltSessionAttributes クラスと JoltSession クラスが用意されています。

JoltSessionAttributes クラスには、さまざまなプロパティのほか、Jolt および Oracle Tuxedo システムへの接続プロパティが格納されます。接続を確立するには、クライアント アプリケーション側で JoltSession クラスのインスタンスを作成する必要があります。このインスタンスが JoltSession オブジェクトです。開発者が Jolt セッションおよび Oracle Tuxedo オブジェクトをインスタンス化すると、Jolt および Oracle Tuxedo のログオン機能が有効になります。endSession メソッドを呼び出すと、セッションは終了し、ユーザのログオフが可能になります。

同期型のサービス呼び出し

要求や応答などのトランザクションは、JoltRemoteService オブジェクト (JoltRemoteService クラスのインスタンス) を使用して処理されます。各 JoltRemoteService オブジェクトは、エクスポートされた Oracle Tuxedo の要求/応答サービスを参照します。JoltRemoteService オブジェクトを使用する前には、サービス名と JoltSession オブジェクトを指定して、JoltRemoteService オブジェクトをインスタンス化しておく必要があります。

JoltRemoteService オブジェクトを使用するには、次の手順に従います。

  1. 入力パラメータを設定します。
  2. サービスを呼び出します。
  3. 出力パラメータを検証します。

効率を高めるため、Jolt では入力パラメータ オブジェクトはコピーされません。オブジェクトへの参照 (文字列とバイト配列) だけが保存されます。JoltRemoteService オブジェクトは、ステートフル オブジェクトです。そのため、このオブジェクトの入力パラメータとリクエスト属性は、オブジェクトの寿命がある限り維持されます。JoltRemoteService オブジェクトを再利用する前に、clear() メソッドを使用して、属性や入力パラメータをリセットできます。

Jolt はマルチスレッド環境用に設計されているので、Java のマルチスレッド機能を使用して複数の JoltRemoteService オブジェクトを同時に呼び出すことができます。詳細については、「マルチスレッド アプリケーション」を参照してください。

トランザクションの開始、コミット、およびロールバック

Jolt では、トランザクションは JoltTransaction クラスのオブジェクトとして表されます。トランザクションは、トランザクション オブジェクトがインスタンス化されると開始されます。次に示すように、トランザクション オブジェクトの作成時には、タイムアウト値と JoltSession オブジェクトのパラメータが設定されます。

trans = new JoltTransaction(timeout, session)

Jolt では、トランザクションに関与するすべてのサービスに対して明示的なトランザクション モデルを使用します。トランザクション サービスを呼び出すには、JoltTransaction オブジェクトがパラメータとして必要です。また、サービスとトランザクションが同じセッションに属していることも必要です。Jolt では、同じセッションにバインドされていないサービスとトランザクションを使用することはできません。

Jolt のファンド転送の例 (SimXfer.java)」のサンプル コードは、Jolt クラス ライブラリの使い方を示しています。ここでは、JoltSessionAttributes、JoltSession、JoltRemoteService、および JoltTransaction クラスを使用しています。

例では、ユーザ定義された 2 つの Oracle Tuxedo サービス (WITHDRAWAL と DEPOSIT) をバインドして、TRANSFER トランザクションを擬似的に実行します。WITHDRAWAL 操作が失敗した場合は、ロールバックが実行されます。それ以外の場合は DEPOSIT が実行され、commit によりトランザクションが完了します。

Jolt のファンド転送の例 (SimXfer.java)」のサンプル コードに示すトランザクション プロセスのプログラミング手順は、以下のとおりです。

  1. hostnameportnumber などの接続属性を JoltSessionAttribute オブジェクトに設定します。
  2. コード リストで次の行を参照してください。

    sattr = new JoltSessionAttributes();
  3. sattr.checkAuthenticationLevel() を使うと、サーバへのログオンに必要なセキュリティ レベルをアプリケーション側で決定できます。
  4. コード リストで次の行を参照してください。

    switch (sattr.checkAuthenticationLevel())
  5. JoltSession オブジェクトをインスタンス化してログオンします。
  6. コード リストで次の行を参照してください。

    session = new JoltSession (sattr, userName, userRole, 
    userPassword, appPassword);

    この例では、SessionException エラーを明示的に捕捉しません。

  7. すべての JoltRemoteService 呼び出しでは、サービスの指定と JoltSession() から返されたセッション キーが必要です。
  8. コード リストで次の行を参照してください。

    withdrawal = new JoltRemoteService(“WITHDRAWAL”, session);
    deposit = new JoltRemoteService(“DEPOSIT”, session);

    これらの呼び出しは、Jolt リポジトリに格納されている WITHDRAWAL および DEPOSIT のサービス定義を、withdrawal オブジェクトおよび deposit オブジェクトにそれぞれバインドします。WITHDRAWAL および DEPOSIT サービスが Jolt リポジトリで定義されていないと、ServiceException が送出されます。この例では、ServiceException エラーを明示的に捕捉しません。

  9. サービス定義が返されると、アプリケーション固有のフィールド (アカウント番号を示す ACCOUNT_ID や引き出し額を示す SAMOUNT など) に自動的に値が設定されます。
  10. コード リストで次の行を参照してください。

    withdrawal.addInt(“ACCOUNT_ID”, 100000);
    withdrawal.addString(“SAMOUNT”, “100.00”);

    add*() メソッドでは、IllegalAccessError または NoSuchFieldError 例外が送出される場合があります。

  11. JoltTransaction 呼び出しでは、指定した時間内にトランザクションが完了しない場合のタイムアウト値を指定できます。
  12. コード リストで次の行を参照してください。

    trans = new JoltTransaction(5,session);
  13. withdrawal サービスの定義が自動的に設定された後で withdrawal.call(trans) メソッドを呼び出すと、withdrawal サービスが呼び出されます。
  14. コード リストで次の行を参照してください。

    withdrawal.call(trans);
  15. 失敗した WITHDRAWAL はロールバックできます。
  16. コード リストで次の行を参照してください。

    trans.rollback();
  17. または、いったん DEPOSIT が実行されると、すべてのトランザクションがコミットされます。コード リストで次の行を参照してください。
  18. deposit.call(trans);
    trans.commit();

次のコード リストは、Jolt クラスを使用してファンドを転送する簡単なアプリケーションの例です。

コード リスト 5-1 Jolt のファンド転送の例 (SimXfer.java)
/* Copyright 1999 BEA Systems, Inc.  All Rights Reserved */
import bea.jolt.*;
public class SimXfer
{
public static void main (String[] args)
{
JoltSession session;
JoltSessionAttributes sattr;
JoltRemoteService withdrawal;
JoltRemoteService deposit;
JoltTransaction trans;
String userName=null;
String userPassword=null;
String appPassword=null;
String userRole=”myapp”;
        sattr = new JoltSessionAttributes();					
sattr.setString(sattr.APPADDRESS, “//bluefish:8501”);
        switch (sattr.checkAuthenticationLevel())		 
{
case JoltSessionAttributes.NOAUTH:
System.out.println(“NOAUTH\n”);
break;
case JoltSessionAttributes.APPASSWORD:
appPassword = “appPassword”;
break;
case JoltSessionAttributes.USRPASSWORD:
userName = “myname”;
userPassword = “mysecret”;
appPassword = “appPassword”;
break;
}
sattr.setInt(sattr.IDLETIMEOUT, 300);
session = new JoltSession(sattr, userName, userRole,
userPassword, appPassword);
// 転送をシミュレートする
withdrawal = new JoltRemoteService(“WITHDRAWAL”, session);
deposit = new JoltRemoteService(“DEPOSIT”, session);
        withdrawal.addInt(“ACCOUNT_ID”, 100000);
withdrawal.addString(“SAMOUNT”, “100.00”);
        // トランザクションの開始。タイムアウトは 5 秒
trans = new JoltTransaction(5, session);
try
{
withdrawal.call(trans);
}
        catch (ApplicationException e)
{
e.printStackTrace();
            // このサービスでは STATLIN フィールドを
            // クライアント アプリケーションのエラー報告に使用する
System.err.println(withdrawal.getStringDef(“STATLIN”,”NO
STATLIN”));
System.exit(1);
}
        String wbal = withdrawal.getStringDef(“SBALANCE”, “$-1.0”);
        // 文字列を浮動小数に変換する前に「$」記号を削除する
float w = Float.valueOf(wbal.substring(1)).floatValue();
if (w < 0.0)
{
System.err.println(“Insufficient funds”);
trans.rollback();
System.exit(1);
}
else // ファンドの預け入れ/転送をする
{
deposit.addInt(“ACCOUNT_ID”, 100001);
deposit.addString(“SAMOUNT”, “100.00”);
            deposit.call(trans);
String dbal = deposit.getStringDef(“SBALANCE”, “-1.0”);
trans.commit();
            System.out.println(“Successful withdrawal”);
System.out.println(“New balance is: “ + wbal);
            System.out.println(“Successful deposit”);
System.out.println(“New balance is: “ + dbal);
}
        session.endSession();
System.exit(0);
} // main の終了
} // SimXfer の終了

 


Oracle Tuxedo のバッファ型を Jolt で使用する

Jolt では、次の Oracle Tuxedo 組み込みのバッファ型がサポートされています。

注意 : X_OCTET の使用方法は CARRAY と同じです。
X_COMMON および X_C_TYPE の使用方法は VIEW と同じです。

Jolt アプリケーションのプログラマは、Oracle Tuxedo に組み込まれているバッファ型のうち、特に CARRAY (文字配列) および STRING の扱い方を知っておく必要があります。

Oracle Tuxedo の型付きバッファ、データ型、バッファ型に関するすべての情報については、以下のマニュアルを参照してください。

STRING バッファ型を使う

STRING バッファ型は、null 以外の文字配列で構成され、最後が null 文字で終了します。CARRAY とは違って、null 文字までの文字数を指定して転送長を設定できます。STRING バッファは、自己記述型です。そのため、異なる文字セットを使用するマシン間でデータを交換する場合は、Oracle Tuxedo システムによってデータが自動的に変換されます。

注意 : Jolt から STRING へのデータ変換時には、STRING バッファの終端に null 終結文字が自動的に追加されます。Java 文字列は null で終結しないためです。

STRING バッファ型を使うには、次の 2 つの操作が必要です。

  1. バッファ型で使用する Tuxedo サービスを定義します。
  2. STRING バッファ型を使用するコードを記述します。

次の 2 つの節では、これらの手順について例を挙げて説明します。

STRING バッファ型の使い方 (ToUpper.java)」に示すコード ToUpper は、STRING バッファ型が設定されたサービスが Jolt でどのように動作するかを示しています。Oracle Tuxedo サービス ToUpper は、Oracle Tuxedo のサンプル simpapp で利用できます。

Jolt リポジトリ エディタで TOUPPER サービスを定義する

ToUpper.java を実行する前に、Jolt リポジトリ エディタを使用して TOUPPER サービスを定義する必要があります。

注意 : サービスを定義したり、新しいパラメータを追加する方法については、「Jolt リポジトリ エディタを使う」を参照してください。
  1. リポジトリ エディタの [Logon] ウィンドウの [Services] をクリックします。
  2. 図 5-3 TOUPPER サービスを追加する


    TOUPPER サービスを追加する

  3. [Services] ウィンドウで SIMPSERV パッケージの TOUPPER サービスを選択します。
  4. [Edit] をクリックします。
  5. 図 5-4 入力バッファ型と出力バッファ型を STRING に設定する


    入力バッファ型と出力バッファ型を STRING に設定する

  6. [Edit Services] ウィンドウで、STRING の入力バッファ型と STRING の出力バッファ型を定義します。「入力バッファ型と出力バッファ型を STRING に設定する」を参照してください。
  7. TOUPPER サービスの入出力用のパラメータとして STRING を 1 つだけ定義します。
  8. [Save Service] をクリックします。

ToUpper.java クライアント コード

次のコード リスト内に示す Java コード ToUpper.java は、STRING バッファ型が設定されたサービスが Jolt でどのように動作するかを示しています。この例では、STRING バッファ型を使用する Jolt クライアントがサーバにデータを渡す様子を示しています。Oracle Tuxedo サーバはバッファを受け取り、文字列をすべて大文字に変換し、変換後の文字列をクライアントに返します。次の例では、セッション オブジェクトが既にインスタンス化されていることを想定しています。

コード リスト 5-2 STRING バッファ型の使い方 (ToUpper.java)
/* Copyright 1996 BEA Systems, Inc.  All Rights Reserved */
import bea.jolt.*;
public class ToUpper
{
public static void main (String[] args)
{
JoltSession session;
JoltSessionAttributes sattr;
JoltRemoteService toupper;
JoltTransaction trans;
String userName=null;
String userPassword=null;
String appPassword=null;
String userRole=”myapp”;
String outstr;
        sattr = new JoltSessionAttributes();
sattr.setString(sattr.APPADDRESS, “//myhost:8501”);
        switch (sattr.checkAuthenticationLevel())
{
case JoltSessionAttributes.NOAUTH:
break;
case JoltSessionAttributes.APPASSWORD:
appPassword = “appPassword”;
break;
case JoltSessionAttributes.USRPASSWORD:
userName = “myname”;
userPassword = “mysecret”;
appPassword = “appPassword”;
break;
}
sattr.setInt(sattr.IDLETIMEOUT, 300);
session = new JoltSession(sattr, userName, userRole,
userPassword, appPassword);
toupper = new JoltRemoteService (“TOUPPER”, session);
toupper.setString(“STRING”, “hello world”);
toupper.call(null);
outstr = toupper.getStringDef(“STRING”, null);
if (outstr != null)
System.out.println(outstr);
        session.endSession();
System.exit(0);
} // main の終了
} // ToUpper の終了

CARRAY バッファ型を使う

CARRAY バッファ型は、Oracle Tuxedo システムに組み込まれている文字配列による単純なバッファ型です。CARRAY バッファ型のデータはシステム側で解釈されないため、データ型が明らかであっても Jolt クライアント アプリケーションでデータの長さを指定する必要があります。このバッファ型を処理するときは、常に Jolt クライアントでデータの長さを指定してください。

たとえば、Oracle Tuxedo サービスが CARRAY バッファ型を使用する場合、ユーザが 32 ビットの integer を設定すると (Java では integer はビッグエンディアン バイト順)、そのデータは変換されずに Oracle Tuxedo サービスに送信されます。

CARRAY バッファ型を使用するには、まずバッファ型で使用する Tuxedo サービスを定義します。次に、そのバッファ型を使用するコードを記述します。次の 2 つの節では、これらの手順について説明します。

注意 : X_OCTET の使用方法は CARRAY と同じです。

リポジトリ エディタで Tuxedo サービスを定義する

例を実行する前に、Tuxedo の ECHO サービスを作成し、起動する必要があります。ECHO サービスは、バッファを取得し、Jolt クライアントに返します。Jolt リポジトリ エディタを使用して ECHO サービスを定義します。

注意 : サービスを定義したり、新しいパラメータを追加する方法については、「Jolt リポジトリ エディタを使う」を参照してください。
図 5-5 リポジトリ エディタ: ECHO サービスを追加する

リポジトリ エディタ: ECHO サービスを追加する

次の手順に従い、リポジトリ エディタで ECHO サービスを追加します。

  1. リポジトリ エディタで ECHO サービスを追加します。
  2. 入出力用のバッファ型として CARRAY を定義します。
  3. 入出力用のパラメータとして CARRAY を 1 つだけ定義します
注意 : X_OCTET バッファ型を使用する場合は、[Input Buffer Type] フィールドと [Output Buffer Type] フィールドを [X_OCTET] に変更しなければなりません。
図 5-6 リポジトリ エディタ: ECHO サービスを編集する

tryOnCARRAY.java クライアント コード

次のコード リストに示すコードは、CARRAY バッファ型が設定されたサービスが Jolt でどのように動作するかを示しています。Jolt は CARRAY データ ストリームの内部のデータを調べません。したがって、Jolt クライアントと CARRAY サービスのデータ形式を一致させるのはプログラマ側の役割になります。次の例では、セッション オブジェクトが既にインスタンス化されていることを想定しています。

コード リスト 5-3 CARRAY バッファ型の例
/* Copyright 1996 BEA Systems, Inc. All Rights Reserved */
  /* コードからのこの抜粋部分は、バッファ型が CARRAY のサービスに
   * Jolt が対応する様子を示したもの
   */
import java.io.*;
import bea.jolt.*;
class ...
{
...
public void tryOnCARRAY()
{
byte data[];
JoltRemoteService csvc;
DataInputStream din;
DataOutputStream dout;
ByteArrayInputStream bin;
ByteArrayOutputStream bout;
        /*
         * java.io.DataOutputStream を使用してデータをバイト配列に出力する
         */
bout = new ByteArrayOutputStream(512);
dout = new DataOutputStream(bout);
dout.writeInt(100);
dout.writeFloat((float) 300.00);
dout.writeUTF("Hello World");
dout.writeShort((short) 88);
        /*
         * バイト配列を新規バイト配列 "data" にコピーする。
         * 次に Jolt リモート サービス呼び出しを発行する
         */
data = bout.toByteArray();
csvc = new JoltRemoteService("ECHO", session);
csvc.setBytes("CARRAY", data, data.length);
csvc.call(null);
/*
         * JoltRemoteService オブジェクトから応答を獲得する。
         * java.io.DataInputStream を使用して個々の値をそれぞれ
         * バイト配列から引き出す
         */
data = csvc.getBytesDef("CARRAY", null);
if (data != null)
{
bin = new ByteArrayInputStream(data);
din = new DataInputStream(bin);
System.out.println(din.readInt());
System.out.println(din.readFloat());
System.out.println(din.readUTF());
System.out.println(din.readShort());
}
}
}

FML バッファ型を使う

FML (フィールド操作言語) は、型付きバッファとして使用できる柔軟性のあるデータ構造です。FML は、タグ付きの値を格納するデータ構造です。このタグ付きの値には型が付いており、長さを変更することができ、複数のオカレンスを持つ場合があります。FML では、型付きバッファを抽象的なデータ型として扱います。

FML 操作を用いると、データ構造やデータの格納方法を知らなくても、データに対してアクセスしたり、更新を行うことができます。アプリケーション プログラムでは、単に識別子を使ってフィールド化されたバッファのフィールドにアクセスしたり更新するだけで済みます。操作の実行時には、FML のランタイム システムによってフィールドの場所と操作を行うデータ型が決定されます。

FML は、クライアントとサーバがそれぞれ別のコード (Java 言語と C 言語など) で記述されている場合、プラットフォームで扱われるデータ型の仕様が異なる場合、またはクライアント/サーバ間のインタフェースが頻繁に変わる場合の Jolt クライアントでの使用に特に適しています。

次の tryOnFml は、FML バッファ型の使用方法を示しています。この例では、FML バッファを使用する Jolt クライアントがサーバにデータを渡す様子を示しています。サーバはバッファを取得し、データを格納するための新しい FML バッファを作成し、バッファを Jolt クライアントに返します。以下は、サンプル コードの説明です。

tryOnFml.java クライアント コード

次に示す tryOnFml.java の Java コードの抜粋は、バッファ型が FML であるサービスを Jolt から利用する方法を示しています。この例では、セッション オブジェクトが既にインスタンス化されていることを想定しています。

コード リスト 5-4 tryOnFml.java のサンプル コード
/* Copyright 1997 BEA Systems, Inc. All Rights Reserved */

import bea.jolt.*;
class ...
{
...
public void tryOnFml ()
{
JoltRemoteService passFml;
String outputString;
int outputInt;
float outputFloat;
...
passFml = new JoltRemoteService("PASSFML",session);
passFml.setString("INPUTSTRING", "John");
passFml.setInt("INPUTINT", 67);
passFml.setFloat("INPUTFLOAT", (float)12.0);
passFml.call(null);
outputString = passFml.getStringDef("OUTPUTSTRING", null);
outputInt = passFml.getIntDef("OUTPUTINT", -1);
outputFloat = passFml.getFloatDef("OUTPUTFLOAT", (float)-1.0);
System.out.print("String =" + outputString);
System.out.print(" Int =" + outputInt);
System.out.println(" Float =" + outputFloat);
}
}

FML フィールド定義

次の「tryOnFml.f16 のフィールド定義」は、「tryOnFml.java のサンプル コード」の FML フィールド定義を示しています。

コード リスト 5-5 tryOnFml.f16 のフィールド定義
#
# FML フィールド定義テーブル
#
*base 4100
INPUTSTRING 1 string
INPUTINT 2 long
INPUTFLOAT 3 float
OUTPUTSTRING 4 string
OUTPUTINT 5 long
OUTPUTFLOAT 6 float

リポジトリ エディタで PASSFML を定義する

BULKPKG パッケージには、PASSFML サービスが含まれており、tryOnFml.java および tryOnFml.c のコードで使用されます。tryOnFml.java を使用する前に、Jolt リポジトリ エディタを使用して PASSFML サービスを変更する必要があります。

注意 : サービスの定義に関しては、「Jolt リポジトリ エディタを使う」を参照してください。
  1. Jolt リポジトリ エディタの [Edit Services] ウィンドウで PASSFML サービスを定義します。入力バッファ型として FML を定義し、出力バッファ型として FML を定義します。
  2. [Repository Editor] ウィンドウ: PASSFML サービスを編集する」は、PASSFML サービスおよび入力バッファ型 FML と出力バッファ型 FML を示しています。

    図 5-7 [Repository Editor] ウィンドウ: PASSFML サービスを編集する


    [Repository Editor] ウィンドウ: PASSFML サービスを編集する

  3. PASSFML サービスの入力バッファ型と出力バッファ型として FML を定義します。
  4. [Edit] をクリックすると、次の図のような [Edit Parameters] ウィンドウが表示されます。
  5. 図 5-8 PASSFML パラメータを定義する


    PASSFML パラメータを定義する

  6. PASSFML サービスのパラメータを定義します。
  7. PASSFML サービスの各パラメータについて、手順 2 から 4 を繰り返します。

tryOnFml.c サーバ コード

次のコード リストは、FML バッファ型を使用するためのサーバ サイドのコードを示しています。PASSFML サービスは、入力 FML バッファを読み込み、FML バッファを出力します。

コード リスト 5-6 tryOnFml.c のサンプル コード
/*
 * tryOnFml.c 
 *
 * Copyright (c) 1997 BEA Systems, Inc. All rights reserved
 *
 * PASSFML BEA Tuxedo サーバが含まれている
 * 
 */
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <malloc.h>
#include <math.h>
#include <string.h>
#include <fml.h>
#include <fml32.h>
#include <Usysflds.h>
#include <atmi.h>
#include <userlog.h>
#include "tryOnFml.f16.h"
/*
* PASSFML サービスは、入力 fml バッファを読み込み、fml バッファを出力する
 */
void
PASSFML( TPSVCINFO *rqst )
{
FLDLEN len;
FBFR *svcinfo = (FBFR *) rqst->data;
char inputString[256];
long inputInt;
float inputFloat;
FBFR *fml_ptr;
int rt;
if (Fget(svcinfo, INPUTSTRING, 0, inputString, &len) < 0) {
(void)userlog("Fget of INPUTSTRING failed %s",
Fstrerror(Ferror));
tpreturn(TPFAIL, 0, rqst->data, 0L, 0);
}
if (Fget(svcinfo, INPUTINT, 0, (char *) &inputInt, &len) < 0) {
(void)userlog("Fget of INPUTINT failed %s",Fstrerror(Ferror));
tpreturn(TPFAIL, 0, rqst->data, 0L, 0);
}
if (Fget(svcinfo, INPUTFLOAT, 0, (char *) &inputFloat, &len) < 0) {
(void)userlog("Fget of INPUTFLOAT failed %s",
Fstrerror(Ferror));
tpreturn(TPFAIL, 0, rqst->data, 0L, 0);
}
/* FML バッファはそのままの状態で返すことができるが、 */
/* 別の FML バッファに格納して返すことも可能 */
if ((fml_ptr = (FBFR *)tpalloc("FML",NULL,rqst->len))==(FBFR *)NULL) {
(void)userlog("tpalloc failed in PASSFML %s",
tpstrerror(tperrno));
tpreturn(TPFAIL, 0, rqst->data, 0L, 0);
}
if(Fadd(fml_ptr, OUTPUTSTRING, inputString, (FLDLEN)0) == -1) {
userlog("Fadd failed with error: %s", Fstrerror(Ferror));
tpfree((char *)fml_ptr);
tpreturn(TPFAIL, 0, NULL, 0L, 0);
}
if(Fadd(fml_ptr, OUTPUTINT, (char *)&inputInt, (FLDLEN)0) == -1) {
userlog("Fadd failed with error: %s", Fstrerror(Ferror));
tpfree((char *)fml_ptr);
tpreturn(TPFAIL, 0, NULL, 0L, 0);
}
if(Fadd(fml_ptr, OUTPUTFLOAT, (char *)&inputFloat, (FLDLEN)0) == -1) {
userlog("Fadd failed with error: %d\n", Fstrerror(Ferror));
tpfree((char *)fml_ptr);
tpreturn(TPFAIL, 0, NULL, 0L, 0);
}
tpreturn(TPSUCCESS, 0, (char *)fml_ptr, 0L, 0);
}

VIEW バッファ型を使う

VIEW は Oracle Tuxedo 組み込みのバッファ型です。VIEW は、Oracle Tuxedo システムで C 構造体および COBOL レコードを使用するために提供されています。この型付きバッファにより、Oracle Tuxedo のランタイム システムは、実行時に読み込まれる view 記述に基づいて C の構造体や COBOL のレコードのフォーマットを認識します。

VIEW を割り当てると、アプリケーションはバッファ型として VIEW を指定し、view の名前 (view 記述ファイル内の名前) を示すサブタイプを指定します。また、パラメータ名と view 内のフィールド名は一致していなければなりません。Oracle Tuxedo のランタイム システムは構造体のサイズに応じて必要な空間を割り当てるため、アプリケーション側でバッファ長を指定する必要はありません。また、ランタイム システムは、要求または応答の際に送信されるデータ量の計算や、異なるマシン間で送受信されるメッセージのエンコードやデコードを自動的に行います。

次は、Jolt クライアントとサーバサイド アプリケーションがある環境での VIEW バッファ型の使い方の例です。

Jolt クライアントでは、VIEW バッファの文字列に含まれる null 文字は行末文字として扱われ、null 文字の後の文字列は切り捨てられます。

リポジトリ エディタで VIEW を定義する

simpview.java および simpview.c の例を実行する前に、Jolt リポジトリ エディタを使用して VIEW サービスを定義する必要があります。

注意 : サービスの定義に関しては、「Jolt リポジトリ エディタを使う」を参照してください。
図 5-9 リポジトリ エディタ: SIMPVIEW サービスを追加する

リポジトリ エディタ: SIMPVIEW サービスを追加する

次の手順に従って、リポジトリ エディタで VIEW サービスを追加します。

  1. SIMPSERV パッケージに SIMPVIEW サービスを追加します。
  2. SIMPVIEW サービスを定義します。入力バッファ型として VIEW を定義し、出力バッファ型として VIEW を定義します。
  3. 図 5-10 リポジトリ エディタ: SIMPVIEW サービスを編集する


    リポジトリ エディタ: SIMPVIEW サービスを編集する

  4. VIEW サービスのパラメータを定義します。この例では、パラメータとして inIntinStringoutFloatoutInt、および outString があります。
注意 : バッファ型として X_COMMON または X_C_TYPE を使用する場合は、[Input Buffer Type] フィールドと [Output Buffer Type] フィールドに正しいバッファ型を指定する必要があります。また、[Input View Name] フィールドと [Output View Name] フィールドにも、対応する名前を指定してください。

simpview.java クライアント コード

simpview.java のサンプル コード」は、VIEW バッファ型が指定されたサービスが Jolt でどのように動作するかを示しています。クライアント コードは、FML サービスにアクセスするときに使用されるコードと同じです。

注意 : 次のコード リスト内のコードでは、例外は捕捉されません。Jolt の例外は、すべて java.lang.RunTimeException から派生しています。そのため、アプリケーション側で捕捉されない例外は Java 仮想マシンによって捕捉されます (よりよいアプリケーションでは、これらの例外を捕捉して適切な処理を行うべきです)。

次のコード リストに示す例を実行する前に、Jolt リポジトリ エディタを使用して SIMPAPP パッケージに VIEW サービスを追加し、Oracle Tuxedo アプリケーション simpview.c を記述する必要があります。このサービスは、クライアントの VIEW バッファからデータを取り出し、新しいバッファを作成して、新しい VIEW バッファとしてクライアントに返します。次の例では、セッション オブジェクトが既にインスタンス化されていることを想定しています。

コード リスト 5-7 simpview.java のサンプル コード
/* Copyright 1997 BEA Systems, Inc. All Rights Reserved */
/*
* コードからのこの抜粋部分は、バッファ型が VIEW のサービスに
* Jolt が対応する様子を示したもの
*/
import bea.jolt.*;
class ...
{
...
public void simpview ()
{
JoltRemoteService ViewSvc;
String outString;
int outInt;
float outFloat;
// BEA Tuxedo サービスに対応する Jolt サービス "SIMPVIEW" を作成する
ViewSvc = new JoltRemoteService("SIMPVIEW",session);
// SIMPVIEW で必要な入力パラメータを設定する
ViewSvc.setString("inString", "John");
ViewSvc.setInt("inInt", 10);
ViewSvc.setFloat("inFloat", (float)10.0);
// サービスを呼び出す。トランザクションは不要なため、
// "null" パラメータを渡す
ViewSvc.call(null);
// 結果を処理する
outString = ViewSvc.getStringDef("outString", null);
outInt = ViewSvc.getIntDef("outInt", -1);
outFloat = ViewSvc.getFloatDef("outFloat", (float)-1.0);
// 結果を表示する
System.out.print("outString=" + outString + ",");
System.out.print("outInt=" + outInt + ",");
System.out.println("outFloat=" + outFloat);
}
}

VIEW フィールド定義

simpview.v16 のフィールド定義」は、前のコード リスト simpview.java の Oracle Tuxedo VIEW フィールド定義を示しています。

コード リスト 5-8 simpview.v16 のフィールド定義
#
# SIMPVIEW の VIEW。これは入出力用に使用される。
# サービスでは入力と出力で異なる VIEW を使用することもできる。
# 先頭から 3 つは入力用、次の 3 つは出力用のパラメータ
#
VIEW SimpView
$
#type cname fbname count flag size null
string inString - 1 - 32 -
long inInt - 1 - - -
float inFloat - 1 - - -
string outString - 1 - 32 -
long outInt - 1 - - -
float outFloat - 1 - - -
END

simpview.c サーバ コード

次のコード リストで使用される入力バッファ型と出力バッファ型は VIEW です。このコードでは、VIEW バッファ型の入力データを受け付け、同じ VIEW バッファ型のデータを出力します。

コード リスト 5-9 simpview.c のサンプル コード
/*
 * SIMPVIEW.c
 *
 * Copyright (c) 1997 BEA Systems, Inc. All rights reserved
 *
 * SIMPVIEW BEA Tuxedo サーバが含まれている
 *
 */
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <malloc.h>
#include <math.h>
#include <string.h>
#include <fml.h>
#include <fml32.h>
#include <Usysflds.h>
#include <atmi.h>
#include <userlog.h>
#include "simpview.h"
/*
 * simpview.h の内容
*
 *struct SimpView {
*
* char inString[32];
* long inInt;
* float inFloat;
* char outString[32];
* long outInt;
* float outFloat;
*};
*/
/*
* サービスは、入力 VIEW バッファを読み込み、VIEW バッファを出力する
 */
void
SIMPVIEW( TPSVCINFO *rqst )
{
/*
* TPSVCINFO 構造から構造 (VIEWSVC) を取得する
*/
struct SimpView *svcinfo = (struct SimpView *) rqst->data;
/*
* 入力パラメータを UserLog に出力する。ここではエラーは
* チェックされない。
* 通常、SERVER は入力を検証し、
* 不正な入力が検出されると TPFAIL を返す
*/
(void)userlog("SIMPVIEW: InString=%s,InInt=%d,InFloat=%f",
svcinfo->inString, svcinfo->inInt, svcinfo->inFloat);
/*
* 出力フィールドを設定し、呼び出し側に返す
*/

strcpy (svcinfo->outString, "Return from SIMPVIEW");
svcinfo->outInt = 100;
svcinfo->outFloat = (float) 100.00;
/*
* エラーが発生すると、TPFAIL
* tpreturn(TPFAIL, ErrorCode, (char *)svcinfo, sizeof (*svcinfo), 0); が返される
*/
tpreturn(TPSUCCESS, 0, (char *)svcinfo, sizeof (*svcinfo), 0);
}

XML バッファ型を使う

XML バッファ型を使用すると、Oracle Tuxedo アプリケーションで XML を使用して、アプリケーション内やアプリケーション間でデータを交換できるようになります。Oracle Tuxedo アプリケーションでは、XML 型バッファの送受信や、それらのバッファを適切なサーバにルーティングできます。解析など、XML 文書のすべての処理ロジックはアプリケーション側にあります。

整形式の XML 文書は、次の要素から構成されます。

XML バッファ型を使用するには、まずバッファ型で使用する Tuxedo サービスを定義します。次に、そのバッファ型を使用するコードを記述します。次の 2 つの節では、これらの手順について説明します。

注意 : CARRAY 同様に、XML バッファ型は STRING ではなくバイト配列として扱われます。Jolt クライアントと Oracle Tuxedo サービス間でのデータ変換は行われません。

リポジトリ エディタで Tuxedo サービスを定義する

例を実行する前に、Tuxedo の XML サービスを作成し、起動する必要があります。XML サービスは、バッファを取得し、Jolt クライアントに返します。Jolt リポジトリ エディタを使用して XML サービスを定義します。

注意 : サービスを定義したり、新しいパラメータを追加する方法については、「Jolt リポジトリ エディタを使う」を参照してください。
図 5-11 リポジトリ エディタ : XML サービスを追加する

リポジトリ エディタ : XML サービスを追加する

次の手順に従い、リポジトリ エディタで XML サービスを追加します。

  1. リポジトリ エディタで ECHO_XML サービスを追加します。
  2. ECHO_XML サービスの入出力用のバッファ型として XML を定義します。
  3. 入出力用のパラメータとして XML を 1 つだけ指定して ECHO_XML サービスを定義します。
  4. 図 5-12 リポジトリ エディタ: XML サービスを編集する


    リポジトリ エディタ : XML サービスを編集する

simpxml.java クライアント コード

次のコード リストは、XML バッファ型が設定されたサービスが Jolt でどのように動作するかを示しています。Jolt は XML データ ストリームの内部のデータを調べません。したがって、Jolt クライアントと XML サービスのデータ形式を一致させるのはプログラマ側の役割になります。次の例では、セッション オブジェクトが既にインスタンス化されていることを想定しています。

コード リスト 5-10 XML バッファ型の例
/* Copyright 2001 BEA Systems, Inc. All Rights Reserved */
/*
* コードからのこの抜粋部分は、バッファ型が XML のサービスに
* Jolt が対応する様子を示したもの
*/
import java.io.*;
import java.lang.*;
import bea.jolt.*;
public class xmldoc {
    	public static void main (String[] args) {
JoltSessionAttributes sattr;
JoltSession session;
JoltRemoteService echo_xml;
		String inString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><ORDER><HEADER DATE=\"05/13/1999\" ORDERNO=\"22345\"/><COMPANY>ACME</COMPANY><LINE><ITEM MODEL=\"Pabc\" QUANTITY=\"5\">LAPTOP</ITEM></LINE><LINE><ITEM MODEL=\"P500\" QUANTITY=\"15\">LAPTOP</ITEM></LINE></ORDER>";
        		byte data[];
DataInputStream din;
DataOutputStream dout;
ByteArrayInputStream bin;
ByteArrayOutputStream bout;
        		byte odata[];
String outString = null;
String appAddress = null;
        		//...Jolt セッションを作成する。
        		try {
/*
* java.io.DataOutputStream を使用して
* データをバイト配列に出力する
*/
bout = new ByteArrayOutputStream(inString.length());
dout = new DataOutputStream(bout);
dout.writeBytes(inString);
			            /*
* バイト配列を新規バイト配列「data」にコピーする。
* 次に Jolt リモート サービス呼び出しを発行する
*/
data = bout.toByteArray();
} catch (Exception e) {
System.out.println("toByteArray error");
return;
}
        		try {
echo_xml = new JoltRemoteService("ECHO_XML", session);
System.out.println("JoltRemoteService Created");
echo_xml.setBytes("XML", data, data.length);
} catch (Exception e) {
System.out.println("RemoteService call error" + e);
return;
}
        		echo_xml.call(null);
System.out.println("Service Call Returned");
odata = echo_xml.getBytesDef("XML", null);
        		try {
System.out.println("Return String is:" + new String(odata));
} catch (Exception e) {
System.err.println("getByteDef Error");
}
}
}
// class の終了

MBSTRING バッファ型を使う

Tuxedo 9.0 では、Jolt は Tuxedo 8.1 の Tuxedo ATMI で既にサポートされている MBSTRING バッファ型をサポートしています。

Java ではマルチ バイト文字のエンコーディングの標準として Unicode が使用され、Unicode の文字列データ用に String クラスが提供されているので、Jolt MBSTRING のサポートでは Java クライアント サイドの MBSTRING コンテナとして String クラスが使用されます。Jolt では、Jolt クライアントと Tuxedo サーバの間でデータが転送されるときに、String オブジェクト内の Unicode MBSTRING データがバイト配列 MBSTRING データ (ATMI の MBSTRING 表現) に、またはその逆に自動的に変換されます。

bea.jolt.Message インタフェース、および bea.jolt.JoltMessage クラスと bea.jolt.JoltRemoteService クラスに追加されたメソッドは以下のとおりです。

addMBString
setMBString
setMBStringItem
getMBStringDef
getMBStringItemDef

MBSTRING バッファ型の使い方は、STRING バッファ型とほとんど同じです。ただし、Jolt リポジトリ エディタで指定されるバッファ型は MBSTRING で、MBSTRING データを取得および設定するための Java メソッドは上記のとおりです。

また、Tuxedo サーバに送信される MBSTRING データのエンコーディング名を指定するために、次の Java システム プロパティが使用されます。

bea.jolt.mbencoding

MBSTRING データを Tuxedo サーバに送信するときに Unicode MBSTRING データを対応するバイト配列 MBSTRING データに変換するために使用される Tuxedo エンコード名。このプロパティが指定されていない場合、Java のデフォルト文字エンコーディング名が使用され、対応する Tuxedo エンコーディング名にマップされます。たとえば、デフォルトの日本語版 Windows のエンコーディング名「MS932」は、対応する Tuxedo エンコーディング名「CP932」にマップされ、このプロパティに指定されます。

bea.jolt.mbencodingmap

Jolt クライアントと Tuxedo サーバ間の文字エンコーディング名のマッピングを指定するファイルの絶対パス名。このマッピングが必要なのは、同じ文字エンコーディングの文字エンコーディング名が Java と Tuxedo で異なる場合があるからです。たとえば、デフォルトの日本語版 Windows のエンコーディング名は、Java では MS932 ですが、Tuxedo では CP932 です。このプロパティを指定しない場合、マッピングは行われません。
つまり、Java 文字エンコーディング名が MBSTRING データに直接設定されて Tuxedo サーバに送信され、Tuxedo サーバから受信した MBSTRING データのエンコーディング名が Java エンコーディング名として使用されます。そのエンコーディング名が Java または Tuxedo でサポートされていない場合、変換エラーが発生する場合があります。 bea.jolt.mbencoding または bea.jolt.mbencodingmap を指定するには、jolti18n.jarCLASSPATH に追加する必要があります。jolti18n.jarCLASSPATH に存在しない場合、エンコーディング名は「ISO-8859-1」に設定され、Java コマンドラインでこれらのプロパティを指定しても、Java と Tuxedo の間でエンコーディング名のマッピングは行われません。

 


マルチスレッド アプリケーション

Java ベースのクラス セットである Jolt は、マルチスレッド アプリケーションをサポートします。ただし、Java 言語のさまざまな実装は、言語や環境ごとの機能によって異なります。Jolt のプログラマは、次の事項を知っておく必要があります。

スレッドの状態の種類」では、さまざまな Java の実装でスレッドを使用する際に起こる問題を説明します。また、Jolt プログラムでスレッドを使う例も示します。

注意 : 多くの場合、Java の実装では、ノンプリエンティブではなく、プリエンプティブなスレッドが処理されます。プリエンティブなスレッドとノンプリエンティブなスレッドでは、パフォーマンスやプログラミングの条件が大きく異なります。

スレッドの状態の種類

Java 仮想マシンで同時に実行される個々のタスクをスレッドと呼びます。スレッドの状態には、主に RUNNING、RUNNABLE、および BLOCKED があります。

注意 : Java 仮想マシン (VM) は、同じ優先度が設定されたスレッドをラウンドロビン方式で実行します。

プリエンプティブなスレッド

プリエンティブなスレッドとノンプリエンティブなスレッドでは、Java 仮想マシン (VM) の制御権を放棄するよう実行中のスレッドに対して通知する方法が異なります。プリエンプティブなスレッド環境では通常、ハードウェアのタイマーを周期的にオフになるように設定します。タイマーがオフになると現在のスレッドの状態が RUNNING から RUNNABLE になり、代わりに別のスレッドが実行されます。

ノンプリエンプティブなスレッド

ノンプリエンプティブなスレッド環境のスレッドは、自発的に CPU の制御権を放棄し、RUNNABLE な状態に移行します。Java 言語クラス内の多くのメソッドには、制御権を自発的に放棄するコードが含まれています。これらのコードは通常、長い処理時間のかかる操作に関連付けられています。たとえば、ネットワークからデータを読み込むと、スレッドは通常パケットの到着を待ちます。イベントやリソースが利用可能になるまで待機するスレッドは BLOCKED の状態です。イベントが発生するか、またはリソースが利用できるようになると、そのスレッドは RUNNABLE になります。

Jolt をノンプリエンプティブなスレッドで使う

ノンプリエンプティブなスレッド環境の仮想マシン (例 : Sun Solaris) で Jolt ベースの Java プログラムを実行する場合、次のいずれかが行われる必要があります。

典型的な方法として、実行するコードが長い部分または時間がかかりそうなループのすべてで次の呼び出しを行います。

Thread.currentThread.yield();

このメッセージを送信しないと、Jolt ライブラリで使用されるスレッドはスケジューリングされず、Jolt 操作に不具合が生じます。

ノンプリエンプティブなスレッドを使用する仮想マシンとして知られている唯一のマシンは、Sun プラットフォーム用の Java Developer's Kit (JDK) です。アプレットを JDK 1.3 で実行するには、yield メッセージを必ず送信してください。既に述べたように、メソッドの中には yield を含むものがあります。例外は System.in.read メソッドです。このメッセージはスレッドの切り替えを行いません。これらのメッセージを使用する代わりに、yield を明示的に使用することをお勧めします。

非同期的な処理を行うためにスレッドを使う

スレッドを使用して、Oracle Tuxedo の tpacall() に似た非同期的な処理を Jolt で行うことができます。この機能があれば、非同期的にサービスを要求する機能は必要ありません。この機能が使えるのは Jolt がスレッド セーフであるためです。たとえば、Jolt クライアント アプリケーションは、Oracle Tuxedo サービスにリクエストを送信するスレッドを開始した後で直ちに Oracle Tuxedo サービスに別のリクエストを送信する別のスレッドを開始することができます。したがって、Jolt による tpacall() の呼び出しが同期的であっても、2 つのスレッドが同時に実行されているため、アプリケーションは非同期的です。

Jolt でスレッドを使用する

Jolt クライアントサイドのプログラムまたはアプレットは完全にスレッド セーフです。Jolt がサポートするマルチスレッド アプリケーションでは、クライアント側に次の特徴があります。

次のサンプル コードは、Jolt アプリケーションで 2 つのスレッドを使用する方法を示したものです。

コード リスト 5-11 Jolt でマルチスレッドを使用する (ThreadBank.java)
/* Copyright 1996 BEA Systems, Inc.  All Rights Reserved */
import bea.jolt.*;
public class ThreadBank
{
public static void main (String [] args)
{
JoltSession session;
try
{
JoltSessionAttributes dattr;
String userName = null;
String userPasswd = null;
String appPasswd = null;
String userRole = null;
         // 必要な属性を設定
dattr = new JoltSessionAttributes();
dattr.setString(dattr.APPADDRESS,”//bluefish:8501”);
         // ドメインをインスタンス化する
         // 認証レベルを調べる
switch (dattr.checkAuthenticationLevel())
{
         case JoltSessionAttributes.NOAUTH:
System.out.println(“NOAUTH\n”);
break;
case JoltSessionAttributes.APPASSWORD:
appPasswd = “myAppPasswd”;
break;
case JoltSessionAttributes.USRPASSWORD:
userName = “myName”;
userPasswd = “mySecret”;
appPasswd = “myAppPasswd”;
break;
}
dattr.setInt(dattr.IDLETIMEOUT, 60);
session = new JoltSession (dattr, userName, userRole,
userPasswd, appPasswd);
T1 t1 = new T1 (session);
T2 t2 = new T2 (session);
         t1.start();
t2.start();
         Thread.currentThread().yield();
try
{
while (t1.isAlive() && t2.isAlive())
{
Thread.currentThread().sleep(1000);

}
}
catch (InterruptedException e)
{
System.err.println(e);
if (t2.isAlive())
{
System.out.println(“job 2 is still alive”);
try
{
Thread.currentThread().sleep(1000);
}
catch (InterruptedException e1)
{
System.err.println(e1);
}
}
else if (t1.isAlive())
{ System.out.println(“job1 is still alive”);
try
{
Thread.currentThread().sleep(1000);
}
catch (InterruptedException e1)
{
System.err.println(e1);
}
}
}
session.endSession();
}
catch (SessionException e)
{
System.err.println(e);
}
finally
{
System.out.println(“normal ThreadBank term”);
}
}
}

class T1 extends Thread
{
JoltSession j_session;
JoltRemoteService j_withdrawal;
   public T1 (JoltSession session)
{
j_session=session;
j_withdrawal= new JoltRemoteService(“WITHDRAWAL”,j_session);
}
public void run()
{
j_withdrawal.addInt(“ACCOUNT_ID”,10001);
j_withdrawal.addString(“SAMOUNT”,”100.00”);
try
{
System.out.println(“Initiating Withdrawal from account 10001”);
j_withdrawal.call(null);
String W = j_withdrawal.getStringDef(“SBALANCE”,”-1.0”);
System.out.println(“-->Withdrawal Balance: “ + W);
}
catch (ApplicationException e)
{
e.printStackTrace();
System.err.println(e);
}
}
}
class T2 extends Thread
{
JoltSession j_session;
JoltRemoteService j_deposit;
   public T2 (JoltSession session)
{
j_session=session;
j_deposit= new JoltRemoteService(“DEPOSIT”,j_session);
}
public void run()
{
j_deposit.addInt(“ACCOUNT_ID”,10000);
j_deposit.addString(“SAMOUNT”,”100.00”);
try
{
System.out.println(“Initiating Deposit from account 10000”);
j_deposit.call(null);
String D = j_deposit.getStringDef(“SBALANCE”,”-1.0”);
System.out.println(“-->Deposit Balance: “ + D);
}
catch (ApplicationException e)
{
e.printStackTrace();
System.err.println(e);
}
}
}

 


イベント サブスクリプションおよびイベント通知

Jolt を使用してクライアント アプリケーションを開発するプログラマは、Oracle Tuxedo サービスまたはほかの Oracle Tuxedo クライアントからイベント通知を受信することができます。Jolt クラス ライブラリには、イベントに基づく通信を処理するため、次の Oracle Tuxedo 通知をサポートするクラスが用意されています。

イベント サブスクリプション用のクラス

Jolt クラス ライブラリには、Jolt クライアント アプリケーション用の非同期通知メカニズムを実装するための 4 つのクラスが用意されています。

これらのクラスについては、Oracle Jolt API リファレンスを参照してください。

通知イベント ハンドラ

Jolt クライアント アプリケーションでは、非請求メッセージとブローカ経由のイベント通知の両方に対してイベント ハンドラ ルーチン (通知の受信時に呼び出される) が必要になります。Jolt では、1 セッションでサポートされるハンドラは 1 つです。Oracle Tuxedo では、通知の生成元であるイベントを特定することはできません。したがって、特定のイベントが発生したときに、そのイベント特有のハンドラを呼び出すことはできません。

クライアント アプリケーション側では、セッションごとに 1 つのハンドラを用意 (onReply() メソッドをオーバーライド) し、そのセッションでクライアントが受信するすべての通知に対して呼び出されるようにしなければなりません。単一ハンドラによるコールバック関数は、非請求とイベント通知型の両方で使用されます。ハンドラ呼び出しの原因となったイベントを特定し、適切な措置を取ることは (ユーザ定義の) ハンドラ ルーチンの役割です。ユーザがセッション ハンドラをオーバーライドしないと、通知メッセージはデフォルトのハンドラによって暗黙のうちに廃棄されます。

Jolt クライアントは、JoltSession クラスのサブクラスを作成し、onReply() メソッドをユーザ定義された onReply() メソッドでオーバーライドすることによって、コールバック関数を提供します。

Oracle Tuxedo/ATMI クライアントでは、ハンドラ コールバック関数内では、ATMI 呼び出しのサブセットしか使うことができません。この制約は、Jolt クライアントには適用されません。別々のスレッドを使用して、通知をモニタし、イベント ハンドラ メソッドを実行します。Jolt がサポートするすべての機能をハンドラ内から実行することが可能です。Jolt クライアント プログラムに適用される通常の規則 (1 セッションにつき 1 トランザクションなど) は、すべてハンドラにも適用されます。

ハンドラ メソッドの呼び出しは、独立したスレッド内で行われます。別々のスレッドが onReply() メソッドを同時に実行しないようにするため、アプリケーション開発者は必ずそのメソッドに synchronized キーワードを付けるか、またはそのメソッドがスレッド セーフになるように記述します。

Jolt では、ハンドラ ルーチンを有効にする暗黙的なモデルが使用されます。クライアントがイベントをサブスクライブすると、Jolt はそのクライアントのハンドラを内部で有効にしますが、その結果、非請求メッセージの受信も有効になります。Jolt クライアントがイベント通知をサブスクライブする場合は、同時に必ず非請求メッセージも受信します。さらに、これらの 2 種類の通知に対して、単一の onReply() メソッドが呼び出されます。

コネクション モード

Jolt は、コネクション モード (RETAINED) またはコネクションレス モード (RECONNECT) で稼動しているクライアントの通知受信をサポートします。コネクション モード (RETAINED) のクライアントは、すべての通知を受信します。コネクションレス モード (RECONNECT) モードで動作する Jolt クライアントは、Jolt セッション ハンドラ (JSH) へのネットワーク接続がアクティブな間は通知を受信します。ネットワーク接続が切断されている場合、JSH はクライアント宛ての通知のログを記録し、その通知を廃棄します。コネクションレス モード (RECONNECT) で稼動している Jolt クライアントは、ネットワーク接続がアクティブでない間は非請求メッセージまたはイベント通知を受信しません。この間に受信されたメッセージは、JSH によって記録され、廃棄されます。

コネクション モードでの通知処理には、Oracle Tuxedo 環境での Jolt クライアントへの確認付きメッセージ通知の処理も含まれます。JSH がクライアントへの確認付きメッセージ通知を受信し、そのクライアントに対してアクティブなネットワーク接続が確立されていない場合、JSH はエラーのログを記録し、通知メッセージに対して不成功を示す確認を返します。

通知データ バッファ

クライアントが通知を受信する場合、通知にはデータ バッファが付随しています。データ バッファはどの Oracle Tuxedo データ バッファ型でもかまいません。Jolt クライアント (ハンドラ) はこれらのバッファを JoltMessage オブジェクトとして受信し、適切な JoltMessage クラスの get*() メソッドを使用してこのオブジェクトからデータを取り出します。

通知に使用するバッファの定義を Jolt リポジトリに格納する必要はありません。ただし、Jolt クライアント アプリケーションのプログラマは、フィールド名を知っておく必要があります。

Jolt システムには、Oracle Tuxedo の tptypes() と同様の機能はありません。FML および VIEW のバッファ型の場合は、適切なフィールド名を指定して get*() メソッドを使用してデータにアクセスします。たとえば、次のように入力します。

getIntDef ("ACCOUNT_ID", -1);

STRING および CARRAY のバッファ型の場合は、バッファ型と同じ名前でデータにアクセスします。たとえば、次のように入力します。

getStringDef ("STRING", null);
getBytesDef ("CARRAY", null);

STRING と CARRAY のバッファ型には、単一のデータ要素しか含まれていません。この要素全体は、get*() メソッドで返されます。

Oracle Tuxedo のイベント サブスクリプション

Oracle Tuxedo のブローカ経由のイベント通知により、Oracle Tuxedo プログラムは、どのプログラムがイベントの発生通知を受信するかを気にしないで、イベントをポストすることができます。また、Jolt のイベント通知機能により、Jolt クライアント アプリケーションは、Oracle Tuxedo の tpnotify() または tpbroadcast() を呼び出してブロードキャストまたはポストされる Oracle Tuxedo イベントをサブスクライブすることができます。

Jolt クライアントがサブスクライブできるのは、Oracle Tuxedo の他のコンポーネントによって生成されたイベントまたはメッセージ通知 (Oracle Tuxedo のサービスまたはクライアントなど) のみです。Jolt クライアントは、イベントまたはメッセージ通知を送信することはできません。

サポートされているサブスクリプションの種類

Jolt では、メッセージ通知型のサブスクリプションしかサポートされません。サブスクリプションが実行されると onReply() メソッドが呼び出されます。Jolt の API では、メッセージ通知の受信時にサービス ルーチンをディスパッチしたり、アプリケーション キューにメッセージを入れる機能はサポートされていません。

通知をサブスクライブする

Jolt クライアントが単一のイベント通知をサブスクライブする場合、クライアントは、非請求メッセージとイベント通知を両方とも受信します。イベントをサブスクライブすることにより、暗黙的に非請求メッセージも利用できるようになります。つまり、たとえばアプリケーションがイベント X に対して JoltUserEvent オブジェクトを作成した場合に tpnotify() または tpbroadcast() を呼び出すと、クライアントは自分宛てのメッセージを自動的に受信します。

注意 : 単一のイベント通知をサブスクライブするために非請求メッセージを用いることはお勧めしません。非請求メッセージを受信したい場合は、アプリケーション側で明示的に指定してください (JoltUserEvent クラスで説明)。次の節では、通知のアンサブスクライブについて説明します。

通知をアンサブスクライブする

イベント通知または非請求メッセージのいずれか、または両方のサブスクライブを停止するには、JoltUserEvent の unsubscribe メソッドを使う必要があります。Jolt では、unsubscribe メソッドを使用して非請求メッセージの受信を停止しても、すべてのサブスクリプション通知が停止されるわけではありません。この点が Oracle Tuxedo と異なります。Oracle Tuxedo では、NULL ハンドラを指定して tpsetunsol() を呼び出すと、すべてのサブスクリプション通知が停止します。

イベントの通知をアンサブスクライブする場合、次の点に注意してください。

クライアント アプリケーションで非請求メッセージの受信を停止したい場合は、すべてのイベントをアンサブスクライブする必要があります。

Jolt API を使用して Oracle Tuxedo からの通知を受信する

非同期型通知」のコード リストは、Jolt クラス ライブラリを使用して通知を受信する方法を示しています。ここでは、JoltSession クラス、JoltReply クラス、JoltMessage、および JoltUserEvent クラスが使用されています。

コード リスト 5-12 非同期型通知
class EventSession extends JoltSession
{
public EventSession( JoltSessionAttributes attr, String user,
String role, String upass, String apass )
{
super(attr, user, role, upass, apass);
}
/**
    * デフォルトの非請求メッセージ ハンドラをオーバーライドする
    * @param reply 非請求メッセージのプレース ホルダ
    * @see bea.jolt.JoltReply
*/
public void onReply( JoltReply reply )
{
        // 1 つのフィールドしか含まない STRING バッファ型のメッセージを
        // 出力する。フィールド名は、「STRING」でなければならない。
        // メッセージに CARRAY バッファ型を使用する場合、フィールド名は
        // 「CARRAY」でなければならない。その他のバッファの場合は、フィールド名は
        // FML または VIEW の要素に従っていなければならない
        JoltMessage msg = (JoltMessage) reply.getMessage();
System.out.println(msg.getStringDef("STRING", "No Msg"));
}
public static void main( Strings args[] )
{
JoltUserEvent  unsolEvent;
JoltUserEvent   helloEvent;
EventSession    session;
...
        // 非請求メッセージを出力できる独自のセッション オブジェクトを
        // インスタンス化する。次に、メッセージに STRING バッファ型を使用する、
        // HELLO イベントと非請求メッセージを
        // サブスクライブする
        session = new EventSession(...);

helloEvent = new JoltUserEvent("HELLO", null, session);
unsolEvent = new JoltUserEvent(JoltUserEvent.UNSOLMSG, null,
session);
...
        // HELLO イベントと非請求メッセージのサブスクライブを停止する
        helloEvent.unsubscribe();
        unsolEvent.unsubscribe();
}
}

 


パラメータ値をクリアする

Jolt クラス ライブラリには、オブジェクトの既存の属性値を消去し、事実上オブジェクトの再利用ができるようにする clear() メソッドが用意されています。「Jolt オブジェクトの再利用 (reuseSample.java)」は、clear() メソッドを使用してパラメータ値をクリアする方法と JoltRemoteService のパラメータ値を再利用する方法を示しています。この例では、再利用するためにサービスを破棄する必要がないことを示しています。代わりに、svc.clear(); 文を使用して既存の入力パラメータ値を廃棄してから addString() メソッドを再度使用しています。

コード リスト 5-13 Jolt オブジェクトの再利用 (reuseSample.java)
/* Copyright 1999 BEA Systems, Inc. All Rights Reserved */
import java.net.*;
import java.io.*;
import bea.jolt.*;
/*
 * これは、各呼び出しの後に JoltRemoteService を再利用する
 * 方法を示したサンプル プログラム
 */
class reuseSample
{
private static JoltSession s_session;
static void init( String host, short port )
{
/* Tuxedo ドメインに接続する準備をする*/
JoltSessionAttributes attr = new JoltSessionAttributes();
attr.setString(attr.APPADDRESS,”//”+ host+”:” + port);
        String username = null;
String userrole = “sw-developer”;
String applpasswd = null;
String userpasswd = null;
        /* 設定された認証レベルを調べる*/
switch (attr.checkAuthenticationLevel())
{
case JoltSessionAttributes.NOAUTH:
break;
case JoltSessionAttributes.APPASSWORD:
applpasswd = “secret8”;
break;
case JoltSessionAttributes.USRPASSWORD:
username = “myName”;
userpasswd = “BEA#1”;
applpasswd = “secret8”;
break;
}
        /* アイドル タイムアウトなし (0) でログオンする*/
/* ログオフするまでネットワーク接続を維持する*/
attr.setInt(attr.IDLETIMEOUT, 0);
s_session = new JoltSession(attr, username, userrole,
userpasswd, applpasswd);
}
    public static void main( String args[] )
{
String host;
short port;
JoltRemoteService svc;
        if (args.length != 2)
{
System.err.println(“Usage: reuseSample host port”);
System.exit(1);
}
        /* 初期化用にホスト名とポート番号を取得する*/
host = args[0];
port = (short)Integer.parseInt(args[1]);
        init(host, port);
        /* DELREC サービスのオブジェクト参照を取得する。
         * このサービスには出力パラメータはなく、入力
         * パラメータのみである
         */
svc = new JoltRemoteService(“DELREC”, s_session);
try
{
/* 入力パラメータ REPNAME を設定する*/
svc.addString(“REPNAME”, “Record1”);
svc.call(null);
/* 再利用する前に入力パラメータを変更する */
svc.setString(“REPNAME”, “Record2”);
svc.call(null);
            /* 入力パラメータを単に廃棄する */
svc.clear();
svc.addString(“REPNAME”, “Record3”);
svc.call(null);
}
catch (ApplicationException e)
{
System.err.println(“Service DELREC failed: “+
e.getMessage()+” “+ svc.getStringDef(“MESSAGE”, null));
}
        /* ログオフし、オブジェクトを廃棄する*/
s_session.endSession();
}
}

 


オブジェクトを再利用する

次の「Jolt リモート サービスを拡張する (extendSample.java)」は、JoltRemoteService クラスをサブクラス化する 1 つの方法を示しています。この例では、JoltRemoteService クラスをサブクラス化して TransferService クラスを作成します。TransferService クラスは JoltRemoteService クラスを拡張し、Oracle Tuxedo の BANKAPP の TRANSFER サービスを利用する Transfer 機能を追加しています。

次のサンプル コードでは、Java 言語の extends キーワードが使用されています。extends キーワードは、Java でベース クラス (親クラス) をサブクラス化するのに使用されます。次のコードは、JoltRemoteService を拡張する方法のうちの 1 つです。

コード リスト 5-14 Jolt リモート サービスを拡張する (extendSample.java)
/* Copyright 1999 BEA Systems, Inc. All Rights Reserved */
import java.net.*;
import java.io.*;
import bea.jolt.*;
/*
* この Jolt サンプル コードからの抜粋部分は、JoltRemoteService を
* カスタマイズする方法を示したもの。Java 言語の「extends」メカニズムを使用する
*/
class TransferService extends JoltRemoteService
{
public String fromBal;
public String toBal;
    public TransferService( JoltSession session )
{
super(“TRANSFER”, session);
}
    public String doxfer( int fromAcctNum, int toAcctNum, String amount )
{
/* 以前の入力パラメータすべてを消去する */
this.clear();
        /* 入力パラメータを設定する */
this.setIntItem(“ACCOUNT_ID”, 0, fromAcctNum);
this.setIntItem(“ACCOUNT_ID”, 1, toAcctNum);
this.setString(“SAMOUNT”, amount );
        try
{
/* 転送サービスを呼び出す*/
this.call(null);
            /* 出力パラメータを取得する */
fromBal = this.getStringItemDef(“SBALANCE”, 0, null);
if (fromBal == null)
return “No balance from Account “ +
fromAcctNum;
toBal = this.getStringItemDef(“SBALANCE”, 1, null);
if (toBal == null)
return “No balance from Account “ + toAcctNum;
return null;
}
catch (ApplicationException e)
{
/* トランザクション失敗。理由を返す */
return this.getStringDef(“STATLIN”, “Unknown reason”);
}
}
}
class extendSample
{
public static void main( String args[] )
{
JoltSession s_session;
String host;
short port;
TransferService xfer;
String failure;
        if (args.length != 2)
{
System.err.println(“Usage: reuseSample host port”);
System.exit(1);
}
        /* 初期化用にホスト名とポート番号を取得する*/
host = args[0];
port = (short)Integer.parseInt(args[1]);
        /* Tuxedo ドメインに接続する準備をする*/
JoltSessionAttributes attr = new JoltSessionAttributes();
attr.setString(attr.APPADDRESS,”//”+ host+”:” + port);
        String username = null;
String userrole = “sw-developer”;
String applpasswd = null;
String userpasswd = null;
        /* 設定された認証レベルを調べる*/
switch (attr.checkAuthenticationLevel())
{
case JoltSessionAttributes.NOAUTH:
break;
case JoltSessionAttributes.APPASSWORD:
applpasswd = “secret8”;
break;
case JoltSessionAttributes.USRPASSWORD:
username = “myName”;
userpasswd = “BEA#1”;
applpasswd = “secret8”;
break;
}
        /* アイドル タイムアウトなし (0) でログオンする*/
/* ログオフするまでネットワーク接続を維持する*/
attr.setInt(attr.IDLETIMEOUT, 0);
s_session = new JoltSession(attr, username, userrole,
userpasswd, applpasswd);
        /*
         * TransferService は JoltRemoteService を継承し、
         * 標準的な BEA Tuxedo の BankApp の TRANSFER サービスを使用する
         * このサービスは異なるパラメータで 2 回呼び出される。
         * s_session が初期化済みであると仮定していることに注意
         */
        xfer = new TransferService(s_session);
if ((failure = xfer.doxfer(10000, 10001, “500.00”)) != null)
System.err.println(“Tranasaction failed: “ + failure);
else
{
System.out.println(“Transaction is done.”);
System.out.println(“From Acct Balance: “+xfer.fromBal);
System.out.println(“ To Acct Balance: “+xfer.toBal);
}
        if ((failure = xfer.doxfer(51334, 40343, “$123.25”)) != null)
System.err.println(“Tranasaction failed: “ + failure);
else
{
System.out.println(“Transaction is done.”);
System.out.println(“From Acct Balance: “+xfer.fromBal);
System.out.println(“ To Acct Balance: “+xfer.toBal);
}
}
}

 


Jolt アプレットのデプロイとローカライズ

Jolt クラス ライブラリを使うと、クライアントの Web ブラウザから実行する Java アプリケーションを作成することができます。この種のアプリケーションを作成するには、次のアプリケーション開発作業を行います。

次の節では、アプリケーションを開発する際のこれらの注意点について説明します。

Jolt アプレットのデプロイ

Jolt アプレットをデプロイするときは、次の要件を検討してください。

Jolt アプリケーションで Oracle Tuxedo サーバと Jolt サーバを使うためのコンフィグレーションについては『Oracle Tuxedo システムのインストール』を参照してください。次の節では、Jolt アプレットをデプロイする際に一般的にクライアントや Web サーバで考慮すべき点について説明します。

クライアント側の注意事項

Jolt クラスを使用して Java アプレットを記述すると、HTML ページで動作する Java アプレットと同じように機能します。Jolt アプレットは HTML アプレットのタグを使用して HTML ページに埋め込むことができます。

<applet code=“applet_name.class”> </applet>

Jolt アプレットを HTML ページに埋め込むと、HTML ページのロード時にアプレットがダウンロードされます。アプレットは、ダウンロード直後に実行されるように記述することができます。また、ユーザによる操作の実行時、タイムアウト値の到達時、または指定した間隔で実行されるようにコードを記述することもできます。さらに、アプレットのダウンロード時に別のウィンドウが開かれるように設定したり、指定した間隔で周期的に音楽を鳴らすこともできます。プログラマは、アプレットを最初にコーディングする際に、さまざまな設定を行うことができます。

注意 : 新しい HTML ページをブラウザにロードすると、アプレットの実行が停止します。

Web サーバに関する注意事項

Java アプレットで Jolt クラスを使用する場合、Web サーバに Jolt リレーがインストールされていない限り、Jolt サーバと Web サーバ (Java アプレットのダウンロード元の Web サーバ) は同じマシンで実行する必要があります。

Web 管理者が Web サーバをセットアップすると、すべての HTML ファイルの格納先ディレクトリが指定されます。指定されたディレクトリに「classes」という名前のサブディレクトリを作成し、Java クラスのすべてのファイルとパッケージを格納してください。次に例を示します。

<html-dir>/classes/bea/jolt

または、すべての Jolt クラスを含む jolt.jar ファイルを指すように CLASSPATH を設定することもできます。

注意 : Jolt クラスのサブディレクトリは、任意の場所に置くことができます。アクセスしやすいように HTML ファイルと同じディレクトリに置くと便利です。Jolt クラスのサブディレクトリに関する唯一の条件は、Web サーバで利用できることです。

Jolt アプレットの HTML ファイルは、jolt.jar ファイルまたは classes ディレクトリを参照している必要があります。次に例を示します。

    /export/html/
|___ classes/
| |_____ bea/
| | |______ jolt/
| | |_____ JoltSessionAttributes.class
| | |_____ JoltRemoteServices.class
| | |_____ ...
| |_____ mycompany/
| |________ app.class
|___ ex1.html
|___ ex2.html

Web 管理者は、次のように ex1.html に「app」アプレットを指定することができます。

<applet codebase=“classes” code=mycompany.app.class width=400 height=200>

Jolt アプレットをローカライズする

Jolt アプリケーションを多言後で使用する場合は、ローカライズに関わる問題を考慮する必要があります。クライアント側の Web ブラウザで実行するアプリケーション、および Web ブラウザ環境以外で実行するよう設計されたアプリケーションの両方でこの問題を考慮する必要があります。ローカライズの作業は次の 2 つです。

ローカライズの際、Jolt クラス ライブラリのパッケージは、Java 言語および Oracle Tuxedo システムの仕様に従います。Jolt は Java の 16 ビット Unicode 文字を JSH に転送します。JSH には、Unicode をローカルな文字セットに変換するメカニズムが組み込まれています。

Unicode の Java 実装および文字エスケープの詳細については、Java Development Kit (JDK) のマニュアルを参照してください。

 


SSL を使用する

Jolt では、デフォルトのリンク レベルの暗号化の代わりに、安全な優先転送メカニズムとして SSL を使用できます。Jolt で SSL を使用できるようにするには、JSL に対して TUXEDO UBBCONFIG ファイルで「-s secure_port」をコンフィグレーションする必要があります。

JSL 接続ポートが SSL ポートである場合、Jolt クライアント ライブラリは自動的に SSL を選択します。SSL の場合、Jolt クライアントは、X.509 証明書の場所、プライベート キー、パスフレーズの暗号化に使用されるパスフレーズなどの情報を提示する必要があります。

これらの要件に対応するために、JoltSessionAttributes に 5 つの属性が追加されています。

Jolt クライアント ライブラリでは、SSL 通信に対応するサード パーティの Java Secure Socket Extension (JSSE) 実装を使用します。以下の JSSE 実装がテスト済みです。

以下のコード リストは、JSL/JSH との通信時に SSL を使用できるようにする Jolt クライアント コードの例です。

コード リスト 5-15 Jolt クライアント コードでの SSL の使用
import java.util.*;
import bea.jolt.*;
public class simpcl extends Object {
    private String           userName      = null;
    private String           userRole      = null;
    private String           appPassword   = null;
    private String           userPassword  = null;
    private JoltSessionAttributes attr     = null;
    private JoltSession          session   = null;
    private JoltRemoteService    toupper   = null;
    private JoltTransaction      trans     = null;
    // JSL に対して '-s 5555' をコンフィグレーションする
    // Jolt クライアントと JSH の間の通信で SSL を使用する
    private String               address   = new String('//cerebrum:5555');
    public static void main(String args[]) {
        simpcl c = new simpcl();
        c.doTest();
    }
    public void doTest() {
        attr = new JoltSessionAttributes();
        // 以下のセッション属性を追加
        attr.setString(attr.APPADDRESS, address);
        attr.setString(attr.TRUSTSTORE,'c:\\samples\\samplecacerts');
        attr.setString(attr.KEYSTORE, 'c:\\samples\\client\\testkeys');
        // このサンプルでは、パスフレーズによってキー ストアとキーのみが保護される。
        // 必要に応じて、信頼ストアもパスフレーズで保護できるが、
        // このサンプルには含まれていない
        attr.setString(attr.KSPASSPHRASE, 'passphrase');
        attr.setString(attr.KEYPASSPHRASE, 'passphrase');
        attr.setInt(attr.IDLETIMEOUT, 300);
        userName = 'juser';
        userRole = 'JUSER';
        userPassword = 'abcd';
        appPassword = 'abcd';
        session = new JoltSession(attr, userName, userRole, userPassword,
                              appPassword);
        // Tuxedo TOUPPER サービスにアクセスする
        toupper = new JoltRemoteService('TOUPPER', session);
        toupper.addString('STRING', 'string');
        trans = new JoltTransaction(60, session);
        try {
            toupper.call(trans);
        } catch (ApplicationException ae) {
            ae.printStackTrace();
            System.exit(1);
        }
        String retString = toupper.getStringDef('STRING', null);
        trans.commit();
        System.out.println(' returned: ' + retString);
        session.endSession();
        return;
    }
}

  ページの先頭       前  次