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 symbolIDLファイルに次の行を追加した場合と同等です。
#define symbol
-emitAll#includedファイル内で定義されているものも含めて、すべての型を発行します。
-fside発行するバインディングを定義します。sideパラメータは、client、server、serverTIE、all、allTIEのいずれかです。-fserverTIEおよび-fallTIEオプションを指定すると、委譲モデル・スケルトンが発行されます。このフラグを指定しなかった場合は、デフォルトで-fclientに設定されます。
-i include-pathデフォルトでは、インクルード・ファイルは現在のディレクトリから検索されます。このオプションを指定すると、ほかのディレクトリを追加できます。
-keep生成されるファイルがすでに存在している場合は、そのファイルが上書きされません。デフォルトでは、上書きされます。
-noWarn警告メッセージを表示しないようにします。
-oldImplBase1.4より前のJDK ORBと互換性のあるスケルトンを生成します。デフォルトでは、POA継承モデルのサーバー側バインディングが生成されます。このオプションを指定すると、ImplBase継承モデルのクラスであるサーバー側のバインディングが生成されるので、以前のバージョンのJavaプログラミング言語との下位互換性が得られます。
-pkgPrefix type prefixtypeがファイル・スコープで検出された場合は、その型に対して生成されるすべてのファイルについて、生成される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%yyyxxx%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にあるようです。