idlj
コマンドは、指定されたインタフェース定義言語(IDL)ファイルのJavaバインディングを生成する場合に使用します。
形式
idlj [options] idlfile
options
コマンド行オプションです。オプションの順番は任意ですが、idlfile
よりも前に指定する必要があります。「idljのオプション」を参照してください。
idlfile
インタフェース定義言語(IDL)の定義が含まれるファイルの名前です。idlfile
は必須であり、最後に指定する必要があります。
説明
IDL-to-Javaコンパイラは、指定されたIDLファイルについてJavaバインディングを生成します。IDL-to-Javaコンパイラの以前のリリースの中には、idltojava
という名前だったものがあります。
クライアント・バインディングおよびサーバー・バインディングの発行
次のidlj
コマンドは、クライアント側のバインディングを持つMy.idl
という名前のIDLファイルを生成します。
idlj My.idl
以前の構文は次のとおりです。
idlj -fclient My.idl
次の例では、サーバー側のバインディングを生成し、クライアント側のバインディングに加えて、スケルトンを追加します。これらはすべてPortable Object Adapter (継承モデル)です。
idlg -fserver My.idl
クライアント側とサーバー側の両方のバインディングを生成する場合は、次のコマンド(どれも等価)のうちの1つを使用します。
idlj -fclient -fserver My.idl idlj -fall My.idl
使用可能なサーバー側のモデルには、次の2つがあります。
移殖可能サーバント継承モデル
デフォルトのサーバー側のモデルは、移殖可能サーバント継承モデルです。インタフェースMy
がMy.idl
に定義されている場合は、ファイルMyPOA.java
が生成されます。My
インタフェースに対して実装を提供する必要があり、My
インタフェースはMyPOA
クラスから継承する必要があります。MyPOA.java
は、org.omg.PortableServer.Servant
クラスを拡張するストリームベースのスケルトンです。
My
インタフェースは、スケルトンが実装するIDLインタフェースに関連付けられているcallHandler
インタフェースとオペレーション・インタフェースを実装します。
Portable Object Adapter (POA)のPortableServer
モジュールには、ネイティブServant
型を定義します。
Javaプログラミング言語では、Servant
型がJava org.omg.PortableServer.Servant
クラスにマッピングされます。このクラスは、すべてのPOAサーバント実装の基底クラスとして機能し、アプリケーション・プログラマが呼び出すことのできるいくつかのメソッドおよびPOAによって呼び出され、サーバントの動作を制御するためにユーザーがオーバーライドできるメソッドも提供します。
継承モデルのもう1つのオプションは、-oldImplBase
フラグを使用して、Java SE 1.4より前のバージョンのJavaプログラミング言語と互換性のあるサーバー側のバインディングを生成することです。-oldImplBase
フラグは非標準であり、これらのAPIは非推奨です。このフラグを使用するのは、Java SE 1.3で記述された既存のサーバーとの互換性を保つ場合のみです。その場合には既存のmakeファイルを変更し、idlj
コンパイラに-oldImplBase
フラグを追加する必要があります。そうしない場合は、POAベースのサーバー側マッピングが生成されます。下位互換性のあるサーバー側のバインディングを生成するには、次のように実行します。
idlj -fclient -fserver -oldImplBase My.idl idlj -fall -oldImplBase My.idl
インタフェースMy
がMy.idl
に定義されている場合は、ファイル_MyImplBase.java
が生成されます。My
インタフェースに対して実装を提供する必要があり、My
インタフェースは_MyImplBase
クラスから継承する必要があります。
Tieモデル
もう1つのサーバー側モデルは、Tieモデルと呼ばれるものです。このサーバー側モデルは、委譲モデルです。Tieとスケルトンを同時に生成することはできないため、それらは別々に生成する必要があります。次のコマンドによって、Tieモデル用のバインディングが生成されます。
idlj -fall My.idl idlj -fallTIE My.idl
My
インタフェースの場合、前述の2番目のコマンドにより、MyPOATie.java
が生成されます。MyPOATie
クラスのコンストラクタは、委譲を取ります。この例では、デフォルトのPOAモデルを使用しているため、コンストラクタにもPOAが必要です。委譲に対して実装を提供する必要があります。その実装はMyOperations
インタフェースからのみ継承する必要があり、その他のクラスから継承する必要はありません。この実装をORBと一緒に使用するには、次の例に示すように、MyPOATie
クラス内で実装をラップする必要があります。
ORB orb = ORB.init(args, System.getProperties()); // Get reference to rootpoa & activate the POAManager POA rootpoa = (POA)orb.resolve_initial_references("RootPOA"); rootpoa.the_POAManager().activate(); // create servant and register it with the ORB MyServant myDelegate = new MyServant(); myDelegate.setORB(orb); // create a tie, with servant being the delegate. MyPOATie tie = new MyPOATie(myDelegate, rootpoa); // obtain the objectRef for the tie My ref = tie._this(orb);
他の実装から継承しなければならない場合、標準の継承モデルではなくTieモデルを使用することがあります。Javaの場合は、インタフェースの継承の個数に制限はありませんが、クラスの継承に使用できるスロットは1つのみです。継承モデルを使用した場合は、そのスロットが占有されます。Tieモデルを使用した場合は、そのスロットが使用されず、ユーザーが独自の目的で使用できます。これには、間接参照のレベルが1つ導入されるという短所があります。つまり、メソッドを呼び出すときに、余分なメソッド呼出しが1回発生します。
サーバー側の生成では、次のTieモデルのバインディングは、Java SE 1.4よりも前のバージョンでのIDLとJavaプログラミング言語とのマッピングのバージョンと互換性があります。
idlj -oldImplBase -fall My.idl idlj -oldImplBase -fallTIE My.idl
My
インタフェースの場合、これによりMy_Tie.java
が生成されます。My_Tie
クラスのコンストラクタは、impl
オブジェクトを取ります。impl
に対して実装を提供する必要がありますが、この実装はHelloOperations
インタフェースからのみ継承する必要があり、その他のクラスから継承する必要はありません。ただし、この実装をORBと一緒に使用するには、My_Tie
内で実装をラップする必要があります。例:
ORB orb = ORB.init(args, System.getProperties()); // create servant and register it with the ORB MyServant myDelegate = new MyServant(); myDelegate.setORB(orb); // create a tie, with servant being the delegate. MyPOATie tie = new MyPOATie(myDelegate); // obtain the objectRef for the tie My ref = tie._this(orb);
発行されたファイルの代替位置の指定
発行されたファイルを現在のディレクトリ以外のディレクトリに置くには、次の方法でコンパイラを呼び出します。
idlj -td /altdir My.idl
My
インタフェースの場合、バインディングは./My.java
ではなく、/altdir/My.java
に発行されます。
インクルード・ファイルの代替位置の指定
My.idl
ファイルにもう1つのidl
ファイルMyOther.idl
がインクルードされている場合、コンパイラはローカル・ディレクトリにMyOther.idl
があるものと想定します。たとえば、そのファイルが/includes
にある場合は、次のようなコマンドでコンパイラを呼び出します。
idlj -i /includes My.idl
たとえば、/moreIncludes
にあるAnother.idl
もMy.idl
にインクルードされているのであれば、次のコマンドでコンパイラを呼び出します。
idlj -i /includes -i /moreIncludes My.idl
このような形式でinclude
ファイルを指定すると、コマンドが長くなるため、インクルード・ファイルを検索する場所をコンパイラに指示するための別の方法が用意されています。この方法は、環境変数の考え方と似ています。CLASSPATH
変数にリストされているディレクトリ内に、idl.config
という名前のファイルを作成します。そのidl.config
の中に、次の形式で行を指定します。
includes=/includes;/moreIncludes
コンパイラは、このファイルを検索し、インクルード・リストを読み込みます。この例では、2つのディレクトリの間のセパレータはセミコロン(;)になっています。このセパレータは、プラットフォームによって異なります。Windowsプラットフォームではセミコロンを使用し、Oracle Solaris、LinuxおよびOS Xプラットフォームではコロンを使用します。
インクルード・ファイルに対するバインディングの発行
デフォルトでは、コマンド行に指定したidl
ファイルで定義されているインタフェースや構造体などについてのみ、Javaバインディングが生成されます。インクルードされたファイルで定義されている型については、生成されません。たとえば、次の2つのidl
ファイルについて考えてみましょう。
My.idl file: #include <MyOther.idl> interface My { }; MyOther.idl file: interface MyOther { };
このデフォルトの規則に関して注意することがあります。グローバル・スコープに指定した#include
文は、前述のとおりに処理されます。これらの#include
文は、インポート文とみなすことができます。それに対して、他の定義に囲まれたスコープ内に指定した#include
文は、本当の意味での#include
文として処理されます。つまり、インクルードされたファイルにあるコードが、元のファイルにそのまま指定されているかのように処理され、それに対してJavaバインディングが発行されます。例:
My.idl file: #include <MyOther.idl> interface My { #include <Embedded.idl> }; MyOther.idl file: interface MyOther { }; Embedded.idl enum E {one, two, three};
idlj My.idl
を実行すると、次のようなJavaファイルのリストが生成されます。インポート文と見なされる#include
に定義されているため、MyOther.java
は生成されませんでした。ただし、本当の意味での#include
で定義されているため、E.java
は生成されました。Embedded.idl
ファイルがMy
インタフェースのスコープ内にインクルードされていたため、My
のスコープ内(つまり、MyPackage
内)に生成されています。-emitAll
フラグを使用すれば、インクルードされたすべてのファイルにあるすべての型が発行されます。
./MyHolder.java ./MyHelper.java ./_MyStub.java ./MyPackage ./MyPackage/EHolder.java ./MyPackage/EHelper.java ./MyPackage/E.java ./My.java
パッケージの接頭辞の挿入
ABCという名前の会社のために作業していて、次のようなIDLファイルを構築したとしましょう。
Widgets.idl file: module Widgets { interface W1 {...}; interface W2 {...}; };
このファイルをIDL-to-Javaコンパイラから実行すると、W1およびW2に対するJavaバインディングがWidgets
パッケージ内に生成されます。業界の慣例によると、会社のパッケージは、com.<company name>
という名前のパッケージ内に置くことになっています。この慣例に従うには、パッケージ名をcom.abc.Widgets
にするようにしてください。このパッケージ接頭辞をWidgetsモジュールに付加するには、次のコマンドを実行します。
idlj -pkgPrefix Widgets com.abc Widgets.idl
Widgets.idl
をインクルードしているIDLファイルがある場合は、そのコマンドにも-pkgPrefix
フラグが必要です。このフラグを指定しないと、そのIDLファイルは、com.abc.Widgets
パッケージではなく、Widgets
パッケージを検索することになります。
接頭辞が必要なパッケージがいくつもある場合は、前述のidl.config
ファイルで接頭辞を指定する方法が簡単です。パッケージの接頭辞を指定する行は、それぞれPkgPrefix.<type>=<prefix>
の形式で記述します。前述の例では、PkgPrefix.Widgets=com.abc
という行になります。このオプションによって、リポジトリIDは影響を受けません。
コンパイル前のシンボルの定義
コンパイル用のシンボルがIDLファイル内で定義されていない場合は、そのシンボルを定義する必要があります。これは、たとえば、バインディング内にデバッグ・コードを組み入れるときに使用します。idlj -d MYDEF My.idl
コマンドは、My.idl
内に#define MYDEF
という行を指定した場合と同等です。
既存のバインディングの保持
Javaバインディング・ファイルがすでに存在する場合は、-keep
フラグを指定すると、コンパイラによる上書きを回避できます。デフォルトでは、すでに存在するかどうかにかかわらず、すべてのファイルが生成されます。これらのファイルをカスタマイズした場合(ただし、それらの内容が正確であるとき以外はカスタマイズは避ける)、-keep
オプションは有用です。idlj -keep My.idl
コマンドは、まだ存在しないクライアント側のバインディングをすべて発行します。
コンパイルの進捗状況の表示
IDL-to-Javaコンパイラは、実行の各段階でステータス・メッセージを生成します。冗長モードをアクティブ化するには、-v
オプションを使用します: idlj -v My.idl
。
デフォルトでは、コンパイラは冗長モードでは実行されません。
バージョン情報の表示
IDL-to-Javaコンパイラのビルド・バージョンを表示するには、コマンド行で-version
オプションを指定します: idlj -version
。
バージョン情報は、コンパイラによって生成されたバインディング内にも書き込まれています。このオプションをコマンド行に指定すると、それ以外のオプションを指定しても、すべて無視されます。
idljのオプション
-d symbol
IDLファイルに次の行を追加した場合と同等です。
#define symbol
-emitAll
#included
ファイル内で定義されているものも含めて、すべての型を発行します。
-fside
発行するバインディングを定義します。side
パラメータは、client
、server
、serverTIE
、all
、allTIE
のいずれかです。-fserverTIE
および-fallTIE
オプションを指定すると、委譲モデル・スケルトンが発行されます。このフラグを指定しなかった場合は、デフォルトで-fclient
に設定されます。
-i include-path
デフォルトでは、インクルード・ファイルは現在のディレクトリから検索されます。このオプションを指定すると、ほかのディレクトリを追加できます。
-keep
生成されるファイルがすでに存在している場合は、そのファイルが上書きされません。デフォルトでは、上書きされます。
-noWarn
警告メッセージを表示しないようにします。
-oldImplBase
1.4より前のJDK ORBと互換性のあるスケルトンを生成します。デフォルトでは、POA継承モデルのサーバー側バインディングが生成されます。このオプションを指定すると、ImplBase
継承モデルのクラスであるサーバー側のバインディングが生成されるので、以前のバージョンのJavaプログラミング言語との下位互換性が得られます。
-pkgPrefix type prefix
type
がファイル・スコープで検出された場合は、その型に対して生成されるすべてのファイルについて、生成されるJavaパッケージ名にprefix
という接頭辞が付加されます。typeは、トップレベル・モジュールの単純名か、どのモジュールよりも外側で定義されたIDL型の単純名のどちらかです。
-pkgTranslate type package
識別子の中にモジュール名の型が検出されると、生成されるJavaパッケージ内のすべてのファイルについて、識別子の中のその名前がパッケージで置き換えられます。最初にpkgPrefix
が変更されることに注意してください。型の値は、トップ・レベルのモジュールまたはすべてのモジュールの外部で定義されたIDL型の単純名であり、完全なパッケージ名に正確に一致する必要があります。
1つの識別子の中で複数の変換が一致する場合は、次の例で示すように、もっとも長い一致が選ばれます。
コマンド:
pkgTranslate type pkg -pkgTranslate type2.baz pkg2.fizz
変換結果:
type => pkg type.ext => pkg.ext type.baz => pkg2.fizz type2.baz.pkg => pkg2.fizz.pkg
パッケージ名org
、org.omg
、またはorg.omg
のサブパッケージは変換できません。これらのパッケージを変換しようとすると、互換性のないコードが生成され、-pkgTranslate
の後の最初の引数としてそれらのパッケージを使用すると、エラーとして処理されます。
-skeletonName xxx%yyy
xxx%yyy
が、スケルトンに名前を付けるパターンとして使用されます。デフォルトは、POA
基底クラス(-fserver
または-fall
)の場合は%POA
、oldImplBase
クラス(-oldImplBase
)および(-fserver
または-fall
)の場合は_%ImplBase
です。
-td dir
現在のディレクトリではなく、出力ディレクトリとしてdir
が使用されます。
-tieName xxx%yyy
パターンに応じてxxx%yyy
を使用します。デフォルトは、POA
基底クラス(-fserverTie
または-fallTie
)の場合は%POA
、oldImplBase
tieクラス(-oldImplBase
)および(-fserverTie
または-fallTie
)の場合は_%Tie
です。
-v
または-verbose
リリース情報を表示して終了します。
-version
リリース情報を表示して終了します。
制約
グローバル・スコープ内のエスケープされた識別子は、IDLプリミティブ型のObject
またはValueBase
と同じ綴りにすることができません。これは、これらの識別子を持つシンボル表が事前にロードされているためです。これらの再定義を許可すると、元の定義が上書きされてしまいます。これは、おそらく恒久的な制約です。
fixed
というIDL型はサポートされていません。
既知の問題点
グローバル識別子についてインポートが生成されません。予期されないローカルimpl
オブジェクトを呼び出すと、例外を受け取ります。ただし、その原因は、ServerDelegate
DSIコード内のNullPointerException
にあるようです。