このトピックでは、CORBA クライアントアプリケーション作成の基本を学びます。 このレッスンでは次のことを行います。
HelloClient.java を作成するには、次のようにします。
HelloClient.java
// Copyright and License import HelloApp.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; public class HelloClient { static Hello helloImpl; public static void main(String args[]) { try { // create and initialize the ORB ORB orb = ORB.init(args, null); // get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); // Use NamingContextExt instead of NamingContext. This is // part of the Interoperable naming Service. NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); // resolve the Object Reference in Naming String name = "Hello"; helloImpl = HelloHelper.narrow(ncRef.resolve_str(name)); System.out.println("Obtained a handle on server object: " + helloImpl); System.out.println(helloImpl.sayHello()); helloImpl.shutdown(); } catch (Exception e) { System.out.println("ERROR : " + e); e.printStackTrace(System.out); } } }
ここでは、HelloClient.java の各行について、そのコードが何をしているか、またアプリケーションでなぜ必要なのかということを説明します。
基本設定
CORBA クライアントの構造は、多くの Java アプリケーションと同じです。つまり、必要なライブラリパッケージをインポートし、アプリケーションクラスを宣言し、main メソッドを定義し、そして例外の処理を行います。
必要なパッケージのインポート
まず、クライアントクラスに必要なパッケージをインポートします。
import HelloApp.*; // the package containing our stubs import org.omg.CosNaming.*; // HelloClient will use the Naming Service import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; // All CORBA applications need these classes
次に、クライアントクラスを宣言します。
public class HelloClient { // The main() method goes here. }
すべての Java アプリケーションには main() メソッドが必要です。 このメソッドを次のように、HelloClient クラスのスコープ内で宣言します。
public static void main(String args[]) { // The try-catch block goes here. }
どの CORBA プログラムでも、実行時に CORBA システム例外が発生する可能性があるので、main() メソッドの機能は、すべて try-catch ブロック内に記述します。 CORBA プログラムは、呼び出しに伴うプロセス (整列化、非整列化、アップコール) で問題が発生すると、システム例外を発生させます。
このレッスンの例外ハンドラは簡単なもので、どんな問題が起こったかが分かるように、例外の名前とスタックのトレースを標準出力に表示します。
main() の中に、次の try-catch ブロックを記述します。
try { // Add the rest of the HelloClient code here. } catch (Exception e) { System.out.println("ERROR : " + e); e.printStackTrace(System.out); }
整列化と IIOP の作業をすべて行うために、CORBA クライアントはローカルの ORB オブジェクトを必要とします。 各クライアントは、org.omg.CORBA.ORB オブジェクトのインスタンスを生成してから、そのオブジェクト自体に関する特定の情報を渡すことにより、そのオブジェクトを初期化します。
try-catch ブロックの中で、ORB 変数を宣言して初期化します。
ORB orb = ORB.init(args, null);
ORB の init() メソッドの呼び出しはアプリケーションのコマンド行引数に渡されるので、実行時に特定のプロパティを設定できます。
Hello サーバの検索
これでアプリケーションに ORB が備わったので、アプリケーションは必要な実際のサービスの検索を ORB に要請できます。このレッスンでは、このサービスは Hello サーバです。 CORBA クライアントが初期オブジェクト参照を得る方法は数多くありますが、このレッスンのクライアントアプリケーションでは、OMG により指定され、Java IDL で利用可能な COS ネームサービスを利用します。 利用可能なネームサービスがないときに初期オブジェクト参照を得る方法については、「文字列化されたオブジェクト参照の使用」を参照してください。
J2SE v.1.4 のネームサービスには 2 つのオプションがあります。1 つは、一時ネームサービスである tnameserv、もう 1 つは、デーモンプロセスである orbd です。デーモンプロセスには、ブートストラップサービス、一時ネームサービス、持続ネームサービス、およびサーバマネージャが含まれています。 この例では orbd を使用します。
初期ネーミングコンテキストの取得
ネームサービスを利用するための最初のステップは、初期ネーミングコンテキストの取得です。 try-catch ブロックの中で、ORB の初期化の次に、orb.resolve_initial_references() を呼び出してネームサーバへのオブジェクト参照を取得します。
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
文字列 NameService は、すべての CORBA ORB に対して定義されています。 この文字列を渡すと、ORB から初期ネーミングコンテキストが返されます。初期ネーミングコンテキストは、ネームサービスへのオブジェクト参照です。 文字列 NameService は、次のことを示しています。
文字列 NameService は、ネームサービスとして ORBD を使用するときに、一時ネームサービスが使用されることを示しています。 この例では、orbd の一部である持続ネームサービスを使用しています。
オブジェクト参照のナロー変換
CORBA のどのオブジェクト参照とも同様に、objRef は汎用の CORBA オブジェクトです。 これを NamingContextExt オブジェクトとして使うには、適切な型にナロー変換する必要があります。
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
これは、idlj により生成されるヘルパークラスの使用方法です。このクラスの機能は HelloHelper の機能に類似しています。 ここで ncRef オブジェクトは org.omg.CosNaming.NamingContextExt になったので、これを使ってネームサービスにアクセスし、他のサービスを検索することができます。 次のステップで、その処理を行います。
NamingContextExt オブジェクトは J2SE v.1.4 で新たに追加されたもので、Interoperable Naming Service 仕様の一部です。
ネームサービスでのオブジェクト参照の解決
Hello インタフェースを実装している Hello オブジェクトに対してネームサービスでの参照を発行するには、まず、Hello オブジェクトの文字列を識別する必要があります。
String name = "Hello";
最後に、ネームサービスの resolve_str() メソッドに name を渡して Hello サーバへのオブジェクト参照を取得し、その参照を Hello オブジェクトにナロー変換します。
helloImpl = HelloHelper.narrow(ncRef.resolve-str(name)); System.out.println("Obtained a handle on server object: " + helloImpl);
ここで、HelloHelper ヘルパークラスが機能します。 上に示したように、ネームサービスの検出時に resolve-str() メソッドは、一般的な CORBA オブジェクトを返します。 このため、即座に Hello オブジェクトにナロー変換することができます。このオブジェクトは、残りの作業を実行するのに必要なオブジェクト参照です。 次に、オブジェクト参照を取得したことを確認するメッセージを画面に送ります。
sayHello() オペレーションの呼び出し
CORBA の呼び出しは、ローカルオブジェクトでのメソッドの呼び出しに似ています。 回線へのパラメータの整列化、サーバ側 ORB へのルーティング、非整列化、サーバメソッドへのアップコールの配置などの複雑な状況を、クライアント側のプログラマは透過的に把握できます。 コンパイラの生成したコードがプログラマに代わってさまざまな作業を行うので、CORBA では呼び出しのプログラミングは簡単です。
最後に、呼び出しの結果を標準出力に表示し、ORB を明示的にシャットダウンします。
System.out.println(helloImpl.sayHello()); helloImpl.shutdown();
ここで HelloClient.java をコンパイルし、エラーを修正してからレッスンを続けます。
Windows のユーザの方は、このマニュアルのパスのスラッシュ (/) をバックスラッシュ (¥) に置き換えてください。
HelloClient.java をコンパイルするには、次のようにします。
javac HelloClient.java HelloApp/*.java
前のレッスン: Hello World サーバの開発
次のレッスン: Hello World アプリケーションの実行
チュートリアルのホーム: Java IDL 入門
Java IDL トップへ |