idlj(1)

名前
idlj - IDL-to-Javaコンパイラ

idljは、指定されたIDLファイルからJavaバインディングを生成します。

形式

idlj [ options ] idl-file

idl-fileは、インタフェース定義言語(IDL)による定義が入ったファイルの名前です。optionsの順番は任意ですが、idl-fileよりも前に指定する必要があります。

説明

IDL-to-Javaコンパイラは、指定されたIDLファイルに対してJavaバインディングを生成します。バインディングの詳細は、 OMG IDL to Java Language Mapping Specification @
http://docs.oracle.com/javase/7/docs/technotes/guides/idl/mapping/jidlMapping.htmlを参照してください。IDL-to-Javaコンパイラの以前のリリースの中には、idltojavaという名前だったものがあります。

  クライアント・バインディングおよびサーバー・バインディングの発行

My.idlという名前のIDLファイルに対してJavaバインディングを生成するには、次のコマンドを実行します。

idlj My.idl

これにより、クライアント側のバインディングが生成されます。このコマンドは、次のコマンドと等価です。

idlj -fclient My.idl

クライアント側のバインディングには、サーバー側のスケルトンは組み込まれていません。インタフェースに対してサーバー側のバインディングを生成するには、次のコマンドを実行します。

idlj -fserver My.idl

サーバー側のバインディングには、クライアント側のバインディングの他に、スケルトンも含まれています。これらはすべて、POA(つまり継承モデル)クラスです。クライアント側とサーバー側の両方のバインディングを生成する場合は、次のコマンド(どれも等価)のうちの1つを使用します。

idlj -fclient -fserver My.idl
idlj -fall My.idl

サーバー側で可能なモデルは2つあります。継承モデルとTie委譲モデルです。

デフォルトのサーバー側のモデルは、移殖可能サーバント継承モデルです。My.idl内でMyインタフェースが定義されている場合は、MyPOA.javaというファイルが生成されます。この実装はMyに提供し、MyPOAを継承する必要があります。

MyPOA.javaは org.omg.PortableServer.Servant @
http://docs.oracle.com/javase/7/docs/api/org/omg/PortableServer/Servant.htmlを拡張するストリームベースのスケルトンで、スケルトンが実装するIDLインタフェースに関連付けられているInvokeHandlerインタフェースと操作インタフェースを実装します。

Portable Object Adapter(POA) @
http://docs.oracle.com/javase/7/docs/technotes/guides/idl/POA.htmlのPortableServerモジュールは、ネイティブのServant型を定義します。Javaプログラミング言語では、Servant型はJavaのorg.omg.PortableServer.Servantクラスにマップされます。このクラスは、すべてのPOAサーバント実装のベース・クラスとして機能し、アプリケーション・プログラマが呼び出すことのできるいくつかのメソッドの他に、POAそのものによって呼び出され、サーバントの動作を制御するためにユーザーがオーバーライドできるメソッドも提供します。

継承モデルのもう1つのオプションは、-oldImplBaseフラグを使用することで、J2SE 1.4より前のバージョンのJavaプログラミング言語と互換性のあるサーバー側バインディングを生成することです。ただし、-oldImplBaseフラグを使用するのは、標準的な手法ではありません。これらのAPIは今後非推奨になる予定です。このフラグを使用するのは、J2SE 1.3で記述された既存のサーバーとの互換性が必要な場合のみです。その場合には既存のMAKEFILEを変更し、idljコンパイラに-oldImplBaseフラグを追加する必要があります。そうしないと、POAベースのサーバー側マッピングが生成されます。下位互換性のあるサーバー側バインディングを生成するには、次のコマンドを使用します。

idlj -fclient -fserver -oldImplBase My.idl
idlj -fall -oldImplBase My.idl

My.idl内でMyインタフェースが定義されている場合は、_MyImplBase.javaというファイルが生成されます。Myに対してその実装を提供し、この実装は_MyImplBaseから継承する必要があります。

もう1つのサーバー側モデルは、Tieモデルと呼ばれるものです。このサーバー側モデルは、委譲モデルです。Tieとスケルトンを同時に生成することはできないため、それらは別々に生成する必要があります。次のコマンドによって、Tieモデル用のバインディングが生成されます。

idlj -fall My.idl
idlj -fallTIE My.idl

Myというインタフェースの場合、上記の2番目のコマンドにより、MyPOATie.javaが生成されます。MyPOATieのコンストラクタは、delegateを取ります。この例では、デフォルトのPOAモデルを使用しているため、コンストラクタにもpoaが必要です。delegateに対して実装を提供する必要がありますが、この実装は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回発生します。

J2SE 1.4より前のバージョンのJava言語にマッピングするIDLのバージョンと互換性のある、サーバー側のTieモデルのバインディングを生成する方法は、次のとおりです。

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

このような形式でインクルードを指定すると、コマンドが長くて複雑になります。そこで、インクルード・ファイルを検索する場所をコンパイラに指示するための別の方法が用意されています。この方法は、環境変数の考え方と似ています。CLASSPATHにリストされているディレクトリ内にidl.configという名前のファイルを作成します。そのidl.configの中に、次のような形式の行を入れます。

includes=/includes;/moreIncludes

コンパイラは、このファイルを検索し、インクルード・リストを読み込みます。この例では、ディレクトリの間の区切り文字はセミコロン(;)になっています。この区切り文字は、プラットフォームによって異なります。たとえば、Windowsプラットフォームではセミコロンですが、Unixプラットフォームではコロンです。includesの詳細は、 クラス・パスの設定 @
http://docs.oracle.com/javase/7/docs/technotes/tools/index.html#generalを参照してください。

  インクルード・ファイルに対するバインディングの発行

デフォルトでは、コマンドラインに指定したIDLファイルで定義されているインタフェースや構造体などについてのみ、Javaバインディングが生成されます。インクルードされたファイルで定義されている型については生成されません。たとえば、次の2つのIDLファイルについて考えてみましょう。

My.idl

#include <MyOther.idl>
interface My
{
};

MyOther.idl

interface MyOther
{
};

次のコマンドでは、Myに対するJavaバインディングのみが生成されます。

idlj My.idl

My.idlで定義されている型と、My.idlにインクルードされたファイル(この例ではMyOther.idl)で定義されている型すべてについて生成するには、次のコマンドを使用します。

idlj -emitAll My.idl

このデフォルトのルールに関して注意が必要な点があります。グローバル・スコープに指定した#include文は、前述のとおりに処理されます。これらの#include文は、インポート文と見なすことができます。それに対して、他の定義に囲まれたスコープ内に指定した#include文は、本当の意味での#include文として処理されます。つまり、インクルードされたファイルにあるコードが、元のファイルにそのまま指定されているかのように処理され、それに対してJavaバインディングが発行されます。次はその例です。

My.idl

#include <MyOther.idl>
interface My
{
  #include <Embedded.idl>
};

MyOther.idl

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フラグを使用すれば、インクルードされたすべてのファイルにあるすべての型が発行されます。

  パッケージの接頭辞の挿入

ABCという名前の会社のために作業していて、次のようなIDLファイルを構築したとしましょう。

Widgets.idl

module Widgets
{
  interface W1 {...};
  interface W2 {...};
};

このファイルに対してIDL-to-Javaコンパイラを実行すると、W1およびW2に対するJavaバインディングがWidgetsパッケージ内に生成されます。しかし、業界の慣例によると、会社のパッケージは、com.<company name>という名前のパッケージ内に置くことになっています。そのため、Widgetsパッケージでは不十分です。慣例に従うには、パッケージを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

バージョン情報は、コンパイラによって生成されたバインディング内にも書き込まれています。このオプションをコマンドラインに指定すると、それ以外のオプションを指定しても、すべて無視されます。

オプション

    -d symbol
        このオプションは、IDLファイルに次のような行を追加した場合と等価です。

        #define symbol

    -emitAll
        #includeファイル内で定義されているものも含めて、すべての型を発行します。

    -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
        識別子の中にモジュール名typeが検出されると、生成されるJavaパッケージ内のすべてのファイルについて、識別子の中のその名前がpackageで置き換えられます。最初にpkgPrefixの変更が行われます。typeは、トップレベルのモジュールの単純名、またはすべてのモジュールの外部で定義されたIDL型の単純名で、完全なパッケージ名に正確に一致する必要があります。
        1つの識別子の中で複数の変換がマッチする場合は、最も長いマッチが選ばれます。たとえば、次のような引数が指定されている場合は、

          -pkgTranslate foo bar -pkgTranslate foo.baz buzz.fizz

        次のような変換が実施されます。

        foo          => bar
        foo.boo      => bar.boo
        foo.baz      => buzz.fizz
        foo.baz.bar  => buzz.fizz.bar

        次のパッケージ名を変換することはできません。

        o   org

        o   org.omg、またはorg.omgのサブパッケージ
    これらのパッケージ名を変換しようとすると、互換性のないコードが生成され、-pkgTranslateの後の最初の引数としてそれらのパッケージを使用すると、エラーとして扱われます。

    -skeletonName xxx%yyy
        xxx%yyyが、スケルトンに名前を付けるパターンとして使用されます。デフォルトは次のとおりです。

        o   POAベース・クラスの場合は%POA (-fserverまたは-fall)

        o   oldImplBaseクラスの場合は_%ImplBase (-oldImplBaseかつ(-fserverまたは-fall))

    -td dir
        出力ディレクトリとして、現在のディレクトリではなく、dirが使用されます。

    -tieName xxx%yyy
        このパターンに従ってTieに名前が付けられます。デフォルトは次のとおりです。

        o   POA Tieベース・クラスの場合は%POATie (-fserverTieまたは-fallTie)

        o   oldImplBase Tieクラスの場合は%_Tie (-oldImplBaseかつ(-fserverTieまたは-fallTie))

    -nowarn、-verbose
        冗長モードになります。

    -version
        バージョン情報を表示して終了します。

各オプションの詳細は、説明のセクションを参照してください。

制約

    o   グローバル・スコープ内のエスケープされた識別子は、IDLプリミティブ型のObjectまたはValueBaseと同じ綴りにしないでください。これらの識別子については、シンボル表が事前にロードされており、これらの識別子の再定義を許可すると元の定義が上書きされてしまうためです。(これは、おそらく恒久的な制約です。)

    o   fixedというIDL型はサポートされていません。

既知の問題点

    o   グローバル識別子についてインポートが生成されません。予期されないローカルimplを呼び出すと、例外を受け取ります。しかし、その原因は、ServerDelegate DSIコード内のNullPointerExceptionにあるようです。