[ Java & CORBAページへ戻る ]

JavaとIDLとの出会い 〜

CORBA分散オブジェクトの第一歩はIDLの記述からです。IDLの書き方とJavaへの融合を見ていきます。


IDL表現とJava表現

module <identifier>
{
    <type declarations>;
    <constant declarations>;
    <exception declarations>;

    interface <identifier> [:<inheritance>]
    {
         <type declarations>;
         <constant declarations>;
         <attribute declarations>;
         <exception declarations>;
[<op_type>] <identifier> (<parameters>) [raises exception] [context]; : }; interface <identifier> [:<inheritance>] : struct <identifier> { <type_spec> <declarators>; : }; valuetype <identifier> [<value_inheritance_spec>] { (public|private) <type_spec> <declarators>; <type declarations>; <constant declarations>; <attribute declarations>; <exception declarations>;
} };
module
Javaのパッケージに相当する。 階層化する時はmoduleをネストさせる。

interface
Javaのインタフェースに相当する。

operation
Javaでのメソッドに相当するオペレーションを定義する。

exception
CORBAオペレーションを使用する際の例外を定義する。

struct
構造体を定義する。

valuetype
オブジェクトの値渡し(OBV)を使用する際の型を定義する。

注意点

IDLとJavaのデータ型変換

IDL型宣言 Java型宣言 内容
論理 boolean boolean 真偽
文字 char char 8bit -> 16bit UNICODE
wchar char
バイト octet byte
文字列 string String
wstring String
整数 short short 16bit整数
unsigned short
long int 32bit整数
unsigned long
long long long 64bit整数
unsigned long long
浮動小数 float float
double double
long double - not support

IDLからJavaクラスへのマッピング

IDL/Java Language Mapping 2.3で規定されているもの。従来のBOAではなく、POAを用いる場合を示します。

IDLインタフェース型

IDLのinterface型定義から生成されるJavaの型
生成されるJava型 クライアント サーバ 概要
<type>.java IDLインタフェースのJavaクラスでの表現
org.omg.CORBA.Object, <type>Operations, org.omg.CORBA.portable.IDLEntity をextendsしている
<type>Operations.java IDLインタフェースで定義したオペレーションのJavaでの表現。CORBAに依存していない型となっている
<type>Helper.java リモートオブジェクトに関するユーティリティ操作を持つクラス
<type>Holder.java リモートオブジェクトと授受するパラメータを格納する。
_<type>Stub.java クライアント側に存在するスタブコード(プロクシ)
<type>POA.java サーバ側スタブ(スケルトン)コード
<type>POATie.java TIE方式でサーバオブジェクトを作る時に使用する

IDL struct型

IDLのstruct型定義から生成されるJavaの型
生成されるJava型 クライアント サーバ 概要
<type>.java IDL structのJavaクラスでの表現
org.omg.CORBA.portable.IDLEntity をextendsしている。final宣言されている。
<type>Helper.java ユーティリティ操作を持つクラス
<type>Holder.java 授受するパラメータを格納する。

IDL enum型

IDL valuetype型

IDLのvaluetype型定義から生成されるJavaの型
生成されるJava型 クライアント サーバ 概要
<type>.java IDL valuetypeのJavaクラスでの表現
org.omg.CORBA.portable.StreamableValue をimplementsしている。abstract宣言されている。
<type>Helper.java ユーティリティ操作を持つクラス
<type>Holder.java 授受するパラメータを格納する。

IDLからJavaへのマッピング例

下記は、OMGのとあるドメインインタフェース(業界別インタフェース)で制定されている仕様から抜き出した例です。

BasicPublisher.IDLのマッピング例
idlファイル Javaインタフェースファイル
#ifndef _BasicPublisher_IDL_
#define _BasicPublisher_IDL_

#pragma prefix "omg.org"

module BasicPublisher
{
  // type definitions
  typedef long UID;
  typedef sequence<UID> UIDSeq;

  #pragma version UID 1.0
  #pragma version UIDSeq 1.0
  
  // interface definitions
  // Forward Declaration
  interface Subscriber;

  interface Publisher
  {
    enum SubscribeErrorCode
    {
      SUB_TOO_MANY,
      SUB_NOT_REGISTERED
    };
    
    exception SubscribeError {
      SubscribeErrorCode error;
    };

    UID subscribe(in Subscriber sub,
                  in boolean send_ref)
      raises(SubscribeError);

    boolean is_subscribed(in UID sub);

    void unsubscribe(in UID sub)
      raises(SubscribeError);
  };

  interface Subscriber
  {
    void update_subscriber();

    void update_subscriber_from_publisher
      (in Publisher pub);
  };

  #pragma version Publisher 1.0
  #pragma version Subscriber 1.0
    
};

#endif
------ PublisherOperations.java ------
package org.omg.BasicPublisher;

public interface PublisherOperations {
    public int subscribe (org.omg.BasicPublisher.Subscriber sub, 
                          boolean send_ref)
        throws org.omg.BasicPublisher.PublisherPackage.SubscribeError;

    public boolean is_subscribed (int sub);

    public void unsubscribe (int sub)
        throws org.omg.BasicPublisher.PublisherPackage.SubscribeError;
}

------ Publisher.java ------
package org.omg.BasicPublisher;

public interface Publisher
    extends org.omg.CORBA.Object,
            org.omg.BasicPublisher.PublisherOperations,
            org.omg.CORBA.portable.IDLEntity {
}

------ SubscriberOperations.java ------
package org.omg.BasicPublisher;

public interface SubscriberOperations {
    public void update_subscriber ();

    public void update_subscriber_from_publisher
        (org.omg.BasicPublisher.Publisher pub);

}

------ Subscriber.java ------
package org.omg.BasicPublisher;

public interface Subscriber
    extends org.omg.CORBA.Object,
            org.omg.BasicPublisher.SubscriberOperations,
            org.omg.CORBA.portable.IDLEntity {
}

左側のidlファイルは、idlコンパイラを通して右側のJavaインタフェースへ変換されます。idlにおいてmoduleが、Javaのパッケージに対応しています。CORBAのIDLインタフェースはJavaでもインタフェースに対応します。Javaではorg.omg.CORBA.Objectインタフェース、org.omg.CORBA.portable.IDLEntityインタフェース、およびIDLインタフェース中のオペレーション定義に対応するメソッドを定義した<type>Operationsインタフェースを継承しています。

Tips

パッケージ名の階層が深いときには#pragma prefixを用いる

Javaのパッケージは、IDLのmoduleがマッピングされます。Javaではパッケージ名をドメイン名の逆順に並べるので、10階層になることも珍しくありません。これをmoduleだけで記述すると、ネストが複雑になり過ぎてしまいます。そこで、#pragma prefixを使ってmoduleのネストを避けます。

module宣言だけで表現 #pragma prefixを用いて表現
module jp
{
 module gr
 {
  module java_conf
  {
   module torutk
   {
    module atc
    {
     module weather
     {
       // 定義
     }
    }
   }
  }
 }
}
#pragma prefix "atc.torutk.java_conf.gr.jp"

module weather
{
    // 定義
}

注)j2sdk, 1.4で提供されるidljには#pragma prefixを扱う機能がないため、コマンドラインで別途指定する必要があります。

可変長な配列を使用するときにはsequenceを用いる

オペレーションの引数や戻り値、structyavaluetypeのメンバに配列を使用するときは、sequenceを使って新しい型を定義します。sequenceには上限値があるものと無制限のものと2種類を使用することができます。いずれもJavaの配列にマッピングされます。javaの配列は実行時にサイズを動的に指定できるので、どちらも配列にマッピングされるのでしょう。

上限値があるsequenceの定義
IDL記述 Javaへのマッピング
typedef sequence<string, 10> PersonNames;
    :
PersonNames names;
String[] names;
無制限長sequenceの定義
IDL記述 Javaへのマッピング
typedef sequence<string> PersonNames;
    :
PersonNames names;
String[] names;

サーバントを実装するクラスが別なクラスを継承していた場合はTieを用いる

サーバントを実装するのに簡単な方法は、IDL interfaceから生成されるPOAクラスを継承することです。しかし、Javaは単一継承なので、既に他のクラスを継承しているクラスをサーバントにするには、POATieを利用します。

nullを渡したいときは、空文字列や空配列を使用する

オペレーションの引数や戻り値に文字列や配列(またはsequence)を使用する場合、nullを渡すことはできません(CORBAの例外が発生します)。この場合は、空文字列("")やサイズ0の配列(new String[0])を使うとよいでしょう。なお、interface参照やvaluetype型はnullを使用することができるようです(規格を確認してはいませんのでご注意)。

IDL記述 Javaでの実装例
string getMiddleName();
public String getMiddleName() {
  if (middleName == null) {
    return "";
  }
  return middleName;
}

idlからJavaへ〜IDLコンパイラ〜

idlファイルをJavaファイルへ変換するには、各種CORBA実装系が提供するIDLコンパイラを使用します。

VisiBroker
4.1
ORBacus
4.0.3
OpenORB
1.2.0
j2sdk
1.4
コマンド名 idl2java jidl java org.openorb.compiler.IdlCompiler idlj
#pragma prefix処理 -package --prefix-package デフォルトで処理 なし
-pkgPrefixで代用
BOAコード生成 -boa -boa -oldImplBase
POAコード生成 デフォルト デフォルト デフォルト -fall
POA TIEアプローチ デフォルト --tie デフォルト -fallTIE
大文字小文字区別 --case-sensitive
生成ディレクトリ デフォルト(generated) -td

OpenORBによるIDLコンパイル

OpenORBを使って、IDLファイルをコンパイルしてみます。まずOpenORBをインストールします。最新版については、OpenORB Communityのホームページを参照してください。ここではOpenORB 1.2.0を使った場合を紹介します。OpenORBのインストールと環境設定方法については、OpenORB Tipsページをご覧下さい。

IDLコンパイル

IDLコンパイラは、libディレクトリに収められているopenorb_tools-1.2.0.jarに含まれているので、これを実行します。openorb_tools-1.2.0.jarはorg.openorb.compiler.IdlCompilerを起動する設定になっています。

>java -jar c:\java\OpenORB-1.2.0\lib\openorb_tools-1.2.0.jar BasicPublisher.idl
OpenORB IDL Compiler / (c) 2000-2001 Exolab.org
compile : BasicPublisher.idl

>

実行した結果、下記のファイルが生成されました。

>dir generated\org\omg\BasicPublisher
2001/11/03  14:58                  231 Publisher.java
2001/11/03  14:58                3,036 PublisherHelper.java
2001/11/03  14:58                1,126 PublisherHolder.java
2001/11/03  14:58                  562 PublisherOperations.java
2001/11/03  14:42       <DIR>          PublisherPackage
2001/11/03  14:58                2,422 PublisherPOA.java
2001/11/03  14:58                1,545 PublisherPOATie.java
2001/11/03  14:58                  234 Subscriber.java
2001/11/03  14:58                3,071 SubscriberHelper.java
2001/11/03  14:58                1,139 SubscriberHolder.java
2001/11/03  14:58                  385 SubscriberOperations.java
2001/11/03  14:58                1,500 SubscriberPOA.java
2001/11/03  14:58                1,340 SubscriberPOATie.java
2001/11/03  14:58                1,719 UIDHelper.java
2001/11/03  14:58                2,813 UIDSeqHelper.java
2001/11/03  14:58                1,039 UIDSeqHolder.java
2001/11/03  14:58                4,872 _PublisherStub.java
2001/11/03  14:58                2,967 _SubscriberStub.java

>dir generated\org\omg\BasicPublisher\PublisherPackage
2001/11/03  14:58                  998 SubscribeError.java
2001/11/03  14:58                1,442 SubscribeErrorCode.java
2001/11/03  14:58                2,245 SubscribeErrorCodeHelper.java
2001/11/03  14:58                1,294 SubscribeErrorCodeHolder.java
2001/11/03  14:58                3,967 SubscribeErrorHelper.java
2001/11/03  14:58                1,242 SubscribeErrorHolder.java
>

生成されたJavaソースコードのパッケージは、#pragma prefixで指定したomg.orgとmoduleで指定したBasicPublisherが組み合わさってorg.omg.BasicPublisherとなります。

JavaIDLによるIDLコンパイル

Java 2 SDK, Standard Edition, v1.4のIDLコンパイラを使ってIDLファイルをコンパイルしてみます。

>idlj -td generated -fall -pkgPrefix BasicPublisher org.omg BasicPublisher.idl
>

IDLファイル中に日本語コメントが入っていると、Javaソースファイル生成時に漢字が化けてしまっています。

指定したオプションの説明


[ Java & CORBAページへ戻る ]


This page is written by Toru TAKAHASHI.(torutk@02.246.ne.jp)