![]()
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ソースファイル生成時に漢字が化けてしまっています。
指定したオプションの説明