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://java.sun.com/javase/6/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://java.sun.com/javase/6/docs/api/org/omg/PortableServer/Servant.html を拡張するストリームベースのスケルトンで、スケルトンが実装する IDL インタフェースに関連付けられている InvokeHandler インタフェースとオペレーションインタフェースを実装します。

Portable Object Adapter (POA) @
http://java.sun.com/javase/6/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 回発生します。

IDL のバージョンから J2SE 1.4 より前のバージョンの Java 言語へのマッピングと互換性のある、サーバー側の 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

また、もし My.idl に、たとえば /moreIncludes にある Another.idl もインクルードされているのであれば、次のようなコマンドでコンパイラを呼び出します。

idlj -i /includes -i /moreIncludes My.idl

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

includes=/includes;/moreIncludes

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

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

デフォルトでは、コマンド行に指定した IDL ファイルで定義されているインタフェースや構造体などについてのみ、Java バインディングが生成されます。インクルードされたファイルで定義されている型については、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) で定義されている型すべてについて Java バインディングを生成するには、次のコマンドを使用します。

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.<会社名> という名前のパッケージ内に置くことになっています。そのため、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
        v1.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 にあるようです。