Java CORBA Counterプログラム¶
参考 | [#107] |
はじめに¶
JavaでCORBAを使った入門レベルのプログラムとして、カウンターを作ります。
環境は次のとおりです。
JDK | Java SE Development Kit 8u241 |
---|---|
CORBA | JacORB 3.9 |
開発環境 | NetBeans IDE 8.2 |
実行環境 | Windows 10 |
開発環境の準備¶
- Java SE Development Kit 8u241のインストール
JDK 8セットアップ参照 - NetBeans IDE 8.2のインストール
NetBeans 8.2セットアップ参照 - JacORB 3.9のインストールと設定
JacORB参照 - NetBeansのライブラリ管理にJacORBを設定
NetBeansのライブラリ管理にJacORBを設定¶
以下の記述でパスの部分は、JacORB 3.9 のバイナリが、C:\Program Files\Java\jacorb-3.9\
に展開されていた場合の例です。
- NetBeans IDEの[ツール]メニュー > [ライブラリ]で、「Antライブラリ・マネージャ」画面を開き、[新規ライブラリ]で[JacORB 3.9]の名前を指定、[クラスパス]に次を追加
C:\Program Files\Java\jacorb-3.9\lib\jacorb-3.9.jar
C:\Program Files\Java\jacorb-3.9\lib\idl.jar
C:\Program Files\Java\jacorb-3.9\lib\jacorb-omgapi-3.9.jar
C:\Program Files\Java\jacorb-3.9\lib\slf4j-api-1.7.14.jar
C:\Program Files\Java\jacorb-3.9\lib\slf4j-jdk14-1.7.14.jar
- [Javadoc]に次を追加
https://jacorb.github.io/JacORB/
開発の手順¶
- IDLファイルの作成
- サーバー・プログラムの作成
- クライアント・プログラムの作成
- 実行
NetBeansでは、3つのプロジェクトを作成します。
- IDLから生成されるクラスから成るライブラリプロジェクト
- CORBAサーバーのアプリケーションプロジェクト
- CORBAクライアントのアプリケーションプロジェクト
Counter分散プログラムの作成¶
IDLから生成されるクラスから成るライブラリプロジェクト¶
プロジェクトの作成¶
IDLファイルは、複数のプログラム(NetBeansプロジェクト)から利用します。ソースコードの一元管理の観点からIDLファイルのコピーを各プロジェクトに持たせるのは不適切です。そこで、IDLファイルを独立したNetBeansプロジェクトで保持し、IDLファイルから生成されるJavaクラス群をライブラリとして各プログラムから利用する構成とします。
- NetBeansの[ファイル]メニュー > [新規プロジェクト] > [Java] > [Javaクラスライブラリ] で、プロジェクト名を"CounterIdl"として作成
IDLファイルの作成¶
- ソースパッケージ(srcフォルダ)の下に、IDLファイルをファイル名"Counter.idl"で作成
注)NetBeans にはファイル・タイプでIDLがなかったので、[その他] > [空のファイル] で作成 - Counter.idl
interface Counter { void increment(); void decrement(); void setCount(in long count); long getCount(); };
IDLでは、型(interface)は名前空間(module)の配下に作成します。IDL to Javaマッピングでは、IDLのmoduleがJavaのpackageに対応します。
例えば、javaのパッケージ com.torutk.count にIDLで定義したインタフェースを配置したい場合、module定義を使うと次のようなIDLファイルになります。
module com { module torutk { module count { interface Counter { void increment(); // ... }; }; }; };
このようにmoduleを多段に定義するとmoduleのネストが深くなりコードが読みにくくなるので、JacORBのIDLコンパイラのオプションj2packageを指定してJavaのパッケージに対応させるようにしています。
ただし、CORBAのインタフェースリポジトリを扱う場合、タイプIDが、ネストしたmoduleを定義した場合と、j2packageオプションを指定した場合で若干異なる点があるのに留意が必要となります。(JacORB Programming Guideの10.4節参照)
NetBeans のビルドにIDLコンパイルを追加¶
IDLコンパイラはJacORBに付属していますが、NetBeansのビルドプロセスにIDLファイルからJavaソースファイルの生成を組み込んでおくと便利なので、AntタスクでIDLコンパイルを実行できるようにします。
- build.xml に追記
<target name="-pre-compile" depends="idl-compile"/> <target name="idl-compile"> <taskdef name="idlc" classname="org.jacorb.idl.JacIDL" classpath="${libs.JacORB_3.9.classpath}"/> <idlc srcdir="${src.dir}" destdir="${build.generated.sources.dir}/idl"> <i2jpackage names=":com.torutk.count"/> </idlcompile> </target>
NetBeansでプロジェクトをビルドするときに、IDLファイルからJavaソースファイルの生成を実行します。
Javaのソースファイルを生成するタイミングは、Javaソースファイルのコンパイル前にしたいので、-pre-compile
ターゲットをオーバーライドします。
IDLコンパイルを実行することを明示するため、新規にターゲットild-compile
を定義し、-pre-compile
ターゲットのdepends
属性でidl-compile
を指定します。
ターゲットidl-compile
では、JacORBが提供するAntタスク org.jacorb.idl.JacIDL を指定したタスクidlc
を定義してこれを実行します。
taskdefのclasspathで指定しているプロパティ(libs.JacORB_3.9.classpath)は、nbproject/build-impl.xmlの-init-user
ターゲットで読み込むプロパティファイルに定義されています。そのため、project直下にtaskdefを定義すると、まだターゲットが実行される前にtaskdefのclasspathが評価され、未定義のためクラスが見つからないという事象が発生します。
i2jpackageは、IDLのmodule定義(名前空間)をJavaのパッケージに置き換えるパターンを定義します。コロン(:)の左が置き換え前のIDL module名で右が置き換え後のjavaパッケージ名です。左側を空にすると、moduleを定義していないIDLをjavaでパッケージを付けることができます。
続いて、idlファイルがビルド出力ディレクトリにコピーされないよう次の修正をします。- project.properties
- build.classes.excludes=**/*.java,**/*.form + build.classes.excludes=**/*.java,**/*.form,**/*.idl
ビルド¶
プロジェクトをビルドすると、次のようにIDLコンパイルされたソースファイル、クラスファイル、JARファイルが生成されます。
CounterIdl +-- build | +-- classes | | +-- com | | +-- torutk | | +-- count | | +-- Counter.class, CounterHelper.class, CounterHolder.class, CounterOperations.class, | | CounterPOA.class, CounterPOATie.class, _CounterStub.class | +-- generated-sources | +-- idl | +-- com | +-- torutk | +-- count | +-- Counter.java, CounterHelper.java, CounterHolder.java, CounterOperations.java, | CounterPOA.java, CounterPOATie.java, _CounterStub.java +-- dist | +-- CounterIdl.jar +-- src +-- Counter.idl
CORBAサーバーのアプリケーションプロジェクト¶
- [ファイル]メニュー > [新規プロジェクト] > [Java] > [Javaアプリケーション]を選択し[次>]ボタン
プロジェクト名を[CounterServer]として作成 - プロジェクトのプロパティを開き[ライブラリ]で、JacORB 3.9ライブラリとCounterIdlプロジェクトを追加
ソースファイルの作成¶
IDLで定義したインタフェースを実装するCORBAオブジェクトを実装します。
ソースパッケージ(srcフォルダ)の下に パッケージ com.torutk.count.serverを作成し、SimpleCounter.javaを作成します。
- SimpleCounter.java 表示
CORBAを初期化し、CORBAオブジェクトを生成し、ネーミングサービスに登録するサーバープログラムを作成します。
ソースパッケージ(srcフォルダ)の下にMain.javaを作成します。
- Main.java 表示
実行設定¶
- プロジェクトのプロパティを開き[実行]で次を設定
- 引数: -ORBInitRef NameService=corbaloc::localhost:3626/NameService
- VMオプション:
-Dorg.omg.CORBA.ORBClass=org.jacorb.orb.ORB
-Dorg.omg.CORBA.ORBSingletonClass=org.jacorb.orb.ORBSingleton
引数には、ネーミングサービスへ接続するための情報を指定します。ここでは、同じマシン上(localhost)に、ポート番号3626でネーミングサービスを起動しているものとし、そのネーミングサービスに接続する設定です。
VMオプションには、Javaの標準APIで提供するCORBAではなく、サードパーティライブラリのCORBAを使用するための設定を記述します。
CORBAクライアントのアプリケーションプロジェクト¶
- [ファイル]メニュー > [新規プロジェクト] > [Java] > [Javaアプリケーション]を選択し[次>]ボタン
プロジェクト名を[CounterClient]として作成 - プロジェクトのプロパティを開き[ライブラリ]で、JacORB 3.9ライブラリとCounterIdlプロジェクトを追加
ソースファイルの作成¶
CORBAを初期化し、ネーミングサービスからCORBA参照を取得し、サーバーのCORBAオブジェクトのメソッドを呼び出すクライアントプログラムを作成します。
ソースパッケージ(srcフォルダ)の下に パッケージ com.torutk.count.client を作成し、その下にMain.javaを作成します。
- Main.java 表示
実行設定¶
- プロジェクトのプロパティを開き[実行]で次を設定
- 引数: -ORBInitRef NameService=corbaloc::localhost:3626/NameService
- VMオプション:
-Dorg.omg.CORBA.ORBClass=org.jacorb.orb.ORB
-Dorg.omg.CORBA.ORBSingletonClass=org.jacorb.orb.ORBSingleton
実行¶
ネーミングサービスの実行¶
JacORBの実行ディレクトリには、ネーミングサービスを実行するバッチファイル・スクリプトファイルが用意されています。
サーバーやクライアントプログラムから接続するポート番号を明示的に指定して実行します。
D:\work\counter> ns -DOAPort=3626 WARNING Warning - unknown codeset (MS932) - defaulting to ISO-8859-1 WARNING Warning - unknown codeset (MS932) - defaulting to ISO-8859-1 INFO Initialising ORB with ID: INFO InterceptorManager started with 0 Server Interceptors, 0 Client Interceptors and 1 IOR Interceptors INFO NS up
サーバーの実行¶
NetBeans上から実行します。
出力ウィンドウに次が表示されます。
run: INFO Initialising ORB with ID: INFO InterceptorManager started with 0 Server Interceptors, 0 Client Interceptors and 1 IOR Interceptors INFO oid: 00 01 24 48 4D 05 15 02 32 36 10 06 30 46 38 14 14 1B 48 4C ..$HM...26..0F8...HL1B .object is activated INFO Using server ID (1160238886) for transient POA INFO ClientConnectionManager: created new ClientGIOPConnection to 127.0.0.1:3626 (de0a01f) INFO Connected to 127.0.0.1:3626 from local port 51483 Waiting request from client
クライアントの実行¶
NetBeans上から実行します。
出力ウィンドウに次が表示されます。
run: Server Counter = 0 Server Counter = 1 ビルド成功(合計時間: 1秒)