bea ホーム | 製品 | dev2dev | support | askBEA
BEA Logo Tuxedo
 ドキュメントのダウンロード   サイトマップ   用語集 
検索
0

Jolt

 Previous Next Contents Index View as PDF  

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

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

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

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

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

 


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

Jolt クラス・ライブラリには、クライアント・サイドのアプリケーションやアプレット (独立した Java アプリケーションとして実行するか、または Java 対応の Web ブラウザで実行) を開発するための BEA 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 インタープリタのエラーおよび BEA Tuxedo のエラーを例外として返します。「Jolt Class Library Reference」では、Jolt クラスと、各クラスのエラーや例外を一覧表示します。『BEA Jolt API リファレンス』には、エラーと例外のクラス・リファレンスが含まれています。

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

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

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

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

.
 

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

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

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

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

表 5-1 Jolt クライアント/サーバの相互作用

Jolt クライアント

Jolt サーバ

1

attr=new JoltSessionAttributes();

attr.setString(attr.APPADDRESS, “//myhost:8000”);

クライアントを BEA Tuxedo 環境にバインドします。

2

session=new JoltSession(attr, username, userRole, userPassword, appPassword);

クライアントを BEA 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);

BEA Tuxedo サービスを実行します。

7

trans.commit() or trans.rollback();

トランザクションを完了またはロールバックします。

8

balance=withdrawal.getFloatDef(“balance,&drq; (float) 0.0);

結果を取り出します (Jolt サーバ側の動作ではありません)。

9

session.endSession();

クライアントを BEA Tuxedo からログオフさせます。


 

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

  1. JoltSessionAttributes クラスを使用してクライアントを BEA Tuxedo 環境にバインドします。

  2. セッションを確立します。

  3. 変数を設定します。

  4. 必要なトランザクション処理を行います。

  5. クライアントを BEA Tuxedo からログオフさせます。

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

 


Jolt オブジェクト間の関係

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

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


 

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

 


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

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

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

ログオン/ログオフ

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

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

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

要求や応答などのトランザクションは、JoltRemoteService オブジェクト (JoltRemoteService クラスのインスタンス) を使用して処理されます 。各 JoltRemoteService オブジェクトは、エクスポートされた BEA 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 つの BEA Tuxedo サービス (WITHDRAWAL と DEPOSIT) をバインドして、TRANSFER トランザクションを擬似的に実行します。WITHDRAWAL 操作が失敗した場合は、ロールバックが実行されます。それ以外の場合は DEPOSIT が実行され、commit によりトランザクションが完了します。

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

  1. hostnameportnumber などの接続属性を JoltSessionAttribute オブジェクトに設定します。

    コード・リストで次の行を参照してください。

    sattr = new JoltSessionAttributes();

  2. sattr.checkAuthenticationLevel() を使うと、サーバへのログオンに必要なセキュリティ・レベルをアプリケーション側で決定できます。

    コード・リストで次の行を参照してください。

    switch (sattr.checkAuthenticationLevel())

  3. JoltSession オブジェクトをインスタンス化してログオンします。

    コード・リストで次の行を参照してください。

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

    この例では、SessionException エラーを明示的にキャッチしません。

  4. すべての JoltRemoteService 呼び出しでは、サービスの指定と JoltSession() から返されたセッション・キーが必要です。

    コード・リストで次の行を参照してください。

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

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

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

    コード・リストで次の行を参照してください。

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

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

  6. JoltTransaction 呼び出しでは、指定した時間内にトランザクションが完了しない場合のタイムアウト値を指定できます。

    コード・リストで次の行を参照してください。

    trans = new JoltTransaction(5,session);

  7. withdrawal サービスの定義が自動的に設定された後で withdrawal.call(trans) メソッドを呼び出すと、withdrawal サービスが呼び出されます。

    コード・リストで次の行を参照してください。

    withdrawal.call(trans);

  8. 失敗した WITHDRAWAL はロールバックできます。

    コード・リストで次の行を参照してください。

    trans.rollback();

  9. または、いったん DEPOSIT が実行されると、すべてのトランザクションがコミットされます。コード・リストで次の行を参照してください。
    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 の終了

 


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

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

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

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

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

STRING バッファ型を使う

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

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

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

  1. バッファ型で使用する Tuxedo サービスを定義します。

  2. STRING バッファ型を使用するコードを記述します。

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

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

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

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

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

  1. リポジトリ・エディタの [Logon] ウィンドウの [Services] をクリックします。

    図 5-3 TOUPPER サービスを追加する


     

  2. [Services] ウィンドウで SIMPSERV パッケージの TOUPPER サービスを選択します。

  3. [Edit] をクリックします。

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


     

  4. [Edit Services] ウィンドウで、STRING の入力バッファ型と STRING の出力バッファ型を定義します。入力バッファ型と出力バッファ型を STRING に設定するを参照してください。

  5. TOUPPER サービスの入出力用のパラメータとして STRING を 1 つだけ定義します。

  6. [Save Service] をクリックします。

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

次のリスト内に示す Java コード ToUpper.java は、STRING バッファ型が設定されたサービスが Jolt でどのように動作するかを示しています。この例では、STRING バッファ型を使用する Jolt クライアントがサーバにデータを渡す様子を示しています。BEA 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 バッファ型は、BEA Tuxedo システムに組み込まれている文字配列による単純なバッファ型です。CARRAY バッファ型のデータはシステム側で解釈されないため、データ型が明らかであっても Jolt クライアント・アプリケーションでデータの長さを指定する必要があります。このバッファ型を処理するときは、常に Jolt クライアントでデータの長さを指定してください。

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

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

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

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

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

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

図 5-5 リポジトリ・エディタ :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 field definition table
#
*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 を定義します。

    [Repository Editor] ウィンドウ :PASSFML サービスを編集するは、PASSFML サービスおよび入力バッファ型 FML と出力バッファ型 FML を示しています。

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


     

  2. PASSFML サービスの入力バッファ型と出力バッファ型として FML を定義します。

  3. Edit] をクリックすると、次の図のような [Edit Parameters] ウィンドウが表示されます。

    図 5-8 PASSFML パラメータを定義する


     

  4. PASSFML サービスのパラメータを定義します。

  5. 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);
}
/* We could just pass the FML buffer back as is, put lets */
/* 別の 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 は BEA Tuxedo 組み込みのバッファ型です。VIEW は、BEA Tuxedo システムで C 構造体および COBOL レコードを使用するために提供されています。この型付きバッファにより、BEA Tuxedo のランタイム・システムは、実行時に読み込まれる view 記述に基づいて C の構造体や COBOL のレコードのフォーマットを認識します。

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

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

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

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

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

注記 サービスの定義に関しては、Jolt リポジトリ・エディタを使うを参照してください。

図 5-9 リポジトリ・エディタ :SIMPVIEW サービスを追加する


 

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

  1. SIMPSERV パッケージに SIMPVIEW サービスを追加します。

  2. SIMPVIEW サービスを定義します。入力バッファ型として VIEW を定義し、出力バッファ型として VIEW を定義します。

    図 5-10 リポジトリ・エディタ: SIMPVIEW サービスを編集する


     

  3. 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 サービスを追加し、BEA Tuxedo アプリケーション simpview.c を記述する必要があります。このサービスは、クライアントの VIEW バッファからデータを取り出し、新しいバッファを作成して、新しい VIEW バッファとしてクライアントに返します。次の例では、セッション・オブジェクトが既にインスタンス化されていることを想定しています。

コード リスト5-7 simpview.java のコード例

/* Copyright 1997 BEA Systems, Inc. All Rights Reserved */
/*
* コードからのこの抜粋部分は、バッファ型が XML のサービスに
* 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);
// Set the input parametes required for 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 の BEA 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 型バッファを使用すると、BEA Tuxedo アプリケーションで XML を使用して、アプリケーション内やアプリケーション間でデータを交換できるようになります。BEA Tuxedo アプリケーションでは、XML 型バッファの送受信や、それらのバッファを適切なサーバにルーティングできます。解析など、XML 文書のすべての処理ロジックはアプリケーション側にあります。

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

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

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

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

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

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

図 5-11 リポジトリ・エディタ :XML サービスを追加する


 

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

  1. リポジトリ・エディタで ECHO_XML サービスを追加します。

  2. ECHO_XML サービスの入出力用のバッファ型として XML を定義します。

  3. 入出力用のパラメータとして XML を 1 つだけ指定して ECHO_XML サービスを定義します

    図 5-12 リポジトリ・エディタ :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;
        		//...Create Jolt Session 
        		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");
}
}
}
// end of class

 


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

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 を明示的に使用することをお勧めします。

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

スレッドを使用して、BEA Tuxedo のtpacall() に似た非同期的な処理を Jolt で行うことができます。この機能があれば、非同期的にサービスを要求する機能は必要ありません。この機能が使えるのは Jolt がスレッド・セーフであるためです。たとえば、Jolt クライアント・アプリケーションは、BEA Tuxedo サービスにリクエストを送信するスレッドを開始した後で直ちに BEA 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 を使用してクライアント・アプリケーションを開発するプログラマは、BEA Tuxedo サービスまたはほかの BEA Tuxedo クライアントからイベント通知を受信することができます。Jolt クラス・ライブラリには、イベントに基づく通信を処理するため、次の BEA Tuxedo 通知をサポートするクラスが用意されています。

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

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

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

通知イベント・ハンドラ

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

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

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

BEA 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によって記録され、廃棄されます。

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

通知データ・バッファ

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

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

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

getIntDef ("ACCOUNT_ID", -1);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Jolt API を使用して BEA 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);
}
/**
* Override the default unsolicited message handler.
* @param reply a place holder for the unsolicited message
* @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 サービスのオブジェクト・リファレンスを取得する。
* このサービスには出力パラメータはなく、入力
* パラメータは 1 つのみ。
*/
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 クラスを拡張し、BEA 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 をカスタマイズする方法を示したものです。 It uses the Java language “extends” mechanism
*/
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 アプリケーションで BEA Tuxedo サーバと Jolt サーバを使うためのコンフィギュレーションについては『BEA 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 言語および BEA Tuxedo システムの仕様に従います。Jolt は Java の 16ビット Unicode 文字を JSH に転送します。JSH には、Unicode をローカルな文字セットに変換するメカニズムが組み込まれています。

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

 

Back to Top Previous Next
Contact e-docsContact BEAwebmasterprivacy