Java IDL を使用する前に、Java プラットフォームのバージョン 1.4 以降をインストールする必要があります。バージョン 1.4 以降には、idlj コンパイラと同様に、CORBA ベースの分散オブジェクトの開発を可能にするために必要な Application Programming Interface (API) および Object Request Broker (ORB) があります。idlj コンパイラは、IDL から Java 言語へのマッピングを使って IDL インタフェース定義を対応する Java インタフェース、クラス、およびメソッドに変換します。次に、それを使ってクライアントとサーバーコードを実装できます。
ここでは、簡単な IDL インタフェース定義の記述方法と、IDL インタフェースを Java へ翻訳する方法を学びます。また、idlj コンパイラにより生成される各ファイルの目的も説明します。
ここでは、次の項目について説明します。
module HelloApp { interface Hello { string sayHello(); oneway void shutdown(); }; };
OMG IDL は、クライアントオブジェクトによって呼び出されオブジェクト実装によって提供される、インタフェースの記述に使用される言語です。インタフェース定義を OMG IDL で記述すると、インタフェースを完全に定義し、各オペレーションのパラメータを完全に指定することができます。OMG IDL インタフェースには、そのインタフェースのオペレーションを使用するクライアントを開発するために必要な情報がすべて用意されています。
クライアントは、OMG IDL からのマッピングが定義されている言語で記述されます。OMG IDL からクライアントの言語構造へのマッピングは、クライアントの言語に用意されている機能によって異なります。OMG では IDL から別の言語へのマッピングを指定しています。これらの言語には C、C++、Smalltalk、COBOL、Ada、Lisp、Python、および Java があります。OMG IDL の構文をマッピングすると、選んだプログラム言語の対応する構文に翻訳されます。
たとえば、idlj ツールを使うと、IDL インタフェースを Java にマッピングしてクライアントクラスを実装できます。次に同じ IDL を C++ にマッピングし、C++ でサーバーを実装すると、Java クライアント (Java ORB を介して) と C++ サーバー (C++ ORB を介して) は、同一の言語で記述された場合と同様に相互にやり取りができます。
「Hello World」の IDL は、1 つのインタフェースにオペレーションが 2 つだけという、とても簡単なものです。次の 3 ステップで完成します。
CORBA モジュールは、関連するインタフェースと宣言のコンテナの役割を果たす名前空間です。このモジュールは、Java パッケージと厳密に対応しています。IDL ファイル内の各モジュール文は、それぞれ 1 つの Java パッケージ文にマッピングされます。
モジュール文の例を示します。
module HelloApp { // Subsequent lines of code here. };
IDL をコンパイルすると、このモジュール文から package 文が Java コードで生成されます。
Java インタフェースと同様に、CORBA インタフェースは、あるオブジェクトがほかのオブジェクトに対して持つ API 規約を宣言します。IDL のインタフェース文はそれぞれ Java インタフェース文にマッピングされます。
Hello.idl ファイルでは、インタフェース文は次のようになります。
module HelloApp { interface Hello // These lines { // declare the // interface }; // statement. };
IDL をコンパイルすると、この文からインタフェース文が Java コードで生成されます。
CORBA のオペレーションは、サーバーが、そのサーバーを呼び出したクライアントに代わって実行する動作のことです。IDL の各オペレーション文から、対応する Java インタフェースのメソッド文が生成されます。
Hello.idl ファイルでは、オペレーション文は次のようになります。
module HelloApp { interface Hello { string sayHello(); // This line is an operation statement. oneway void shutdown(); // This line is another }; };これで、小さな「Hello World」アプリケーションのインタフェース宣言が完成しました。
idlj
ツールは OMG IDL ファイルを読み込んで、必要な Java ファイルを作成します。idlj コンパイラは、デフォルトでクライアント側のバインディングだけを生成します。クライアント側のバインディングとサーバー側のスケルトンの両方が必要な場合 (「Hello World」プログラムと同様)、idlj コンパイラを実行するときに、-fall オプションを使用する必要があります。コンパイラオプションの詳細については、IDL-to-Java コンパイラオプションを参照してください。
-fall または -fserver のどちらかの引数が使用されるときに生成されるデフォルトのサーバー側マッピングは、CORBA 2.3.1 仕様の第 11 章「POA (Portable Object Adapter)」(formal/99-10-07) に準拠しています。POA の詳細については、ポータブルオブジェクトアダプタを参照してください。
POA (Portable Object Adaptor) を使用する利点は、次のとおりです。
idlj -fall Hello.idl
ディレクトリの内容を一覧表示してみてください。HelloApp という名前のディレクトリが作成され、その中に 6 つのファイルが保存されていることがわかります。テキストエディタで Hello.java を開きます。Hello.java はシグニチャーインタフェースで、指定された型のインタフェースがほかのインタフェースで使用される場合に、メソッド宣言でシグニチャー型として使用されます。次のようになります。
//Hello.java package HelloApp; /** * HelloApp/Hello.java * Generated by the IDL-to-Java compiler (portable), version "3.0" * from Hello.idl */ public interface Hello extends HelloOperations, org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity { } // interface Hello
このインタフェースは簡単なので、IDL 文が生成された Java 文にどのようにマッピングされているかがよくわかります。
IDL 文 | Java 文 | |
---|---|---|
module HelloApp | package HelloApp; | |
interface Hello | public interface Hello |
extends 文に注目してください。必要な CORBA 機能を確実に備えるために、すべての CORBA オブジェクトは org.omg.CORBA.Object から派生しています。必要なコードは idlj により生成されます。ユーザーがマッピングを行う必要はありません。
以前のバージョンの idlj コンパイラ (idltojava とも呼ばれる) では、IDL インタフェースで定義されるオペレーションもこのファイルにあります。J2SDK v1.3.0 から、IDL と Java のマッピングは、CORBA 2.3.1 仕様 (formal/99-10-07) に従って、IDL インタフェースで定義されるすべてのオペレーションをオペレーションインタフェースの HelloOperations.java に記述しています。オペレーションインタフェースは、サーバー側マッピングで使用され、同じ場所にあるクライアントとサーバーに最適化された呼び出しを提供するメカニズムとして使用されます。Hello.idl では、このファイルは次のようになります。
//HelloOperations.java package HelloApp; /** * HelloApp/HelloOperations.java * Generated by the IDL-to-Java compiler (portable), version "3.0" * from Hello.idl */ public interface HelloOperations { String sayHello (); void Shutdown (); } // interface HelloOperations
このインタフェースに定義されているオペレーションは 2 つだけなので、生成された Java 文にどのように IDL 文がマッピングされているのかが簡単にわかります。
IDL 文 | Java 文 | |
---|---|---|
string sayHello(); | String sayHello(); | |
oneway void shutdown(); | void Shutdown (); |
idlj コンパイラではいくつかのファイルが生成されます。実際に生成されるファイルの数は、IDL ファイルのコンパイル時に選択されたオプションによって異なります。生成されたファイルには標準の機能があるので、プログラムを配置して実行するまでは無視してもかまいません。J2SE v1.4 では、Hello.idl の idlj コンパイラで、-fall コマンド行オプションを使って生成されるファイルは次のとおりです。
この abstract クラスは、ストリームベースのサーバースケルトンで、サーバー用に基本的な CORBA 機能を提供します。これは org.omg.PortableServer.Servant を拡張し、InvokeHandler インタフェースと HelloOperations インタフェースを実装します。サーバークラス HelloServant は HelloPOA を拡張します。
このクラスはクライアントスタブで、クライアント用に CORBA 機能を提供します。これは org.omg.CORBA.portable.ObjectImpl を拡張し、Hello.java インタフェースを実装します。
このインタフェースには作成した IDL インタフェースの Java 版が含まれます。Hello.java インタフェースは、標準的な CORBA オブジェクト機能を提供する org.omg.CORBA.Object を拡張します。また HelloOperations インタフェースおよび org.omg.CORBA.portable.IDLEntity も拡張します。
このクラスは補助的な機能を提供します。特に、CORBA オブジェクト参照を適切な型に変換するための narrow() メソッドは重要な役割を果たします。Helper クラスは、CORBA ストリームへのデータ型の入出力、および Any からのデータ型の挿入および抽出を扱います。Holder クラスは Helper クラスのメソッドに入出力を委譲します。
この final クラスは、Hello 型の public インスタンスメンバーを保持します。IDL 型のパラメータが out または inout であれば Holder クラスが使用されます。これは、org.omg.CORBA.portable.OutputStream および org.omg.CORBA.portable.InputStream 引数 (CORBA は許可しますが、Java のセマンティクスには簡単にマッピングできません) に対するオペレーションを提供します。Holder クラスは Helper クラスのメソッドに入出力を委譲します。これは org.omg.CORBA.portable.Streamable を実装します。
このインタフェースには sayHello() メソッドおよび shutdown() メソッドが含まれます。IDL-to-Java マッピングは、IDL インタフェースで定義されたオペレーションをすべてこのファイルに組み込み、スタブとスケルトンで共有します。
IDL インタフェースを記述するときは、目的の分散型アプリケーションに必要なすべてのファイルが生成されるようにプログラムを記述します。次のステップでは、クライアントクラスおよびサーバークラスを実装します。その後のステップでは、HelloClient.java クライアントクラスおよび HelloServer.java サーバークラスを作成します。
Hello.idl に対して idlj を実行しようとしたときに、idlj が見つかりませんでした。ほとんどの場合、実行パスに存在しないことが原因です。idlj (JDK bin ディレクトリ) が実行パスに含まれていることを確認してからやり直してください。
IDL の構造を対応する Java 文にマッピングする処理の基本情報について説明しています。
OMG インタフェース定義言語の完全な仕様を規定しています。仕様は formal/99-10-07 からダウンロードできます。