CORBA分散オブジェクトの第一歩はIDLの記述からです。IDLの書き方とJavaへの融合を見ていきます。
module <identifier> { <type declarations>; <constant declarations>; <exception declarations>; interface <identifier> [:<inheritance>] { <type declarations>; <constant declarations>; <attribute declarations>; <exception declarations>; |
module Javaのパッケージに相当する。 階層化する時はmoduleをネストさせる。 interface Javaのインタフェースに相当する。 operation Javaでのメソッドに相当するオペレーションを定義する。 exception CORBAオペレーションを使用する際の例外を定義する。 struct 構造体を定義する。 valuetype オブジェクトの値渡し(OBV)を使用する際の型を定義する。 |
module animal { interface Cat; // Forward Declaration interface Lion { Cat some_operation(); }; interface Cat { : }; };
型 | 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 Language Mapping 2.3で規定されているもの。従来のBOAではなく、POAを用いる場合を示します。
生成される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方式でサーバオブジェクトを作る時に使用する |
生成されるJava型 | クライアント | サーバ | 概要 |
---|---|---|---|
<type>.java | IDL structのJavaクラスでの表現 org.omg.CORBA.portable.IDLEntity をextendsしている。final宣言されている。 |
||
<type>Helper.java | ユーティリティ操作を持つクラス | ||
<type>Holder.java | 授受するパラメータを格納する。 |
生成されるJava型 | クライアント | サーバ | 概要 |
---|---|---|---|
<type>.java | IDL valuetypeのJavaクラスでの表現 org.omg.CORBA.portable.StreamableValue をimplementsしている。abstract宣言されている。 |
||
<type>Helper.java | ユーティリティ操作を持つクラス | ||
<type>Holder.java | 授受するパラメータを格納する。 |
下記は、OMGのとあるドメインインタフェース(業界別インタフェース)で制定されている仕様から抜き出した例です。
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インタフェースを継承しています。
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を扱う機能がないため、コマンドラインで別途指定する必要があります。
オペレーションの引数や戻り値、structyavaluetypeのメンバに配列を使用するときは、sequenceを使って新しい型を定義します。sequenceには上限値があるものと無制限のものと2種類を使用することができます。いずれもJavaの配列にマッピングされます。javaの配列は実行時にサイズを動的に指定できるので、どちらも配列にマッピングされるのでしょう。
IDL記述 | Javaへのマッピング |
---|---|
typedef sequence<string, 10> PersonNames; : PersonNames names; |
String[] names; |
IDL記述 | Javaへのマッピング |
---|---|
typedef sequence<string> PersonNames; : PersonNames names; |
String[] names; |
サーバントを実装するのに簡単な方法は、IDL interfaceから生成されるPOAクラスを継承することです。しかし、Javaは単一継承なので、既に他のクラスを継承しているクラスをサーバントにするには、POATieを利用します。
オペレーションの引数や戻り値に文字列や配列(または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ファイルへ変換するには、各種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をインストールします。最新版については、OpenORB Communityのホームページを参照してください。ここではOpenORB 1.2.0を使った場合を紹介します。OpenORBのインストールと環境設定方法については、OpenORB Tipsページをご覧下さい。
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となります。
Java 2 SDK, Standard Edition, v1.4のIDLコンパイラを使ってIDLファイルをコンパイルしてみます。
>idlj -td generated -fall -pkgPrefix BasicPublisher org.omg BasicPublisher.idl > |
IDLファイル中に日本語コメントが入っていると、Javaソースファイル生成時に漢字が化けてしまっています。
指定したオプションの説明