CORBA関連のJava技術について

CORBAで実装されたレガシーなサービス(課金関連?)をJavaのWebアプリケーションと連携させる仕事を担当することになりそうなので、今更ですがCORBA関連のJava技術に関して調査してみました。簡単に結果を以下にまとめます。

CORBAとは

Common Object Request Broker Architecture - Wikipediaによると、さまざまな言語で実装されたオブジェクトを分散化された環境で相互に呼び出すためにOMGによって標準化された規格とのこと。IDL(Interface Definition Language)によって言語非依存のインターフェースを定義しておき、Java、C、C++、Ada、COBOLSmalltalkLISPなどさまざまな言語で実装可能となっています。*1つまり、CORBAでは言語透過性、位置透過性が実現されるということです。さらに、リモート呼び出しに加えて、トランザクション、セキュリティ、メッセージングなどの共通サービスに対する規格もあるようです。現在なら、EJBとかWebサービスなどを使うことが普通だと思いますが、10年くらい前までは結構話題になっていたように記憶しています。

分散オブジェクト技術

CORBAの技術が注目されていた時代(15年くらい前でJavaの誕生時期とかぶる)は、それ以前からあるRPC(リモートプロシージャーコール)に対して分散オブジェクト指向という側面が強調されていたようです。単にリモートのステートレスな手続きをサービスとして呼び出すというのではなく、オブジェクト指向プログラミングの発想を拡張してネットワークごしでオブジェクト同士が通信し合うというというのがCORBAで思い描かれる理想形だったと思われます。ただし、実際には

  • プログラミングモデルの複雑さ
  • ネットワーク通信のオーバーヘッド

などの理由により、純粋な分散オブジェクト指向という考え方はほぼ完全に時代遅れになっていると思います。よってCORBAを使うといっても単純に多言語でステートレスなRPCという使い方をしているケースが大半ではないでしょうか。ただし、インターフェースを決めておけば言語によらずにサービスを実装できるということから、信頼できる枯れたCORBAの実装が利用できるのであれば、必ずしもWebサービスなどに置き換えるよりもよいというケースも一応存在すると思います。

標準プロトコルとしてのIIOP

ORBの実装によって本来の通信プロトコルは異なっているが、相互運用のためにGIOP(General InterORB Protocol)という抽象的なプロトコルの規約が決められ、されにそれをTCP/IP上にマッピングしたものがIIOP(Internet InterORB Protocol)とのことです。理論上は、IIOPを通して複数のベンダー間で相互に通信が可能ということになります。なお、ファイアーウォールのポートを開けばWebサービスと同じようにグローバルなネットワーク上で通信可能なはずですが、実際はHTTP以外通さないことが普通で、場合によってはHTTPでラップ(トンネリング)する必要があります。

JavaとCORBAとの関係

JavaプラットフォームにおけるCORBAサポートについては、基本的には以下のドキュメントに記述されています。
CORBA と Java 技術
EJBWebサービスなどの分散技術が一般化する前の時代ではJavaで分散を行うには

  • ソケットやHTTPなどの低レベルの通信を自分で実装する
  • RMIを使う(JDK1.1から)
  • Java IDLを使ってCORBAを使う(JDK1.2から)

のいずれかの手段を使う必要がありました。JavaのWrite Once Run Anywhereという特性と型づけの強いオブジェクト指向言語という特性からCORBAとの相性が良いと注目されていたようです。ちなみに、当時の本を見るとJavaアプレットからCORBAのサービスと通信するなどのサンプルがよく出てきます。
Javaプログラマーとして、CORBA+Javaのプログラミングの方法を理解する上で、重要なことは、

Java CORBA ORB は RMI プログラミングモデルと IDL プログラミングモデルの両方をサポートしています。

ということですね。2つの異なるプログラミングモデルが規格として存在するために少しややこしくなっています。

IDLプログラミングモデル

Java IDLという規格はJDK1.2の当初から存在していました。現在でもJava SE(Java EEではない)の標準APIの中に含まれています。これは、先ほど述べたようにIDLからさまざまな言語へのマッピングのひとつとしてのJava言語へのマッピングです。また、JDK1.3からはPure JavaのIDLコンパイラ(idlj)とORBの実装が付属しています。Java IDLを使えば、別言語で実装されているCORBAのサービスをJavaから呼び出すことができますし、逆にJavaのオブジェクトをCORBAサービスとして公開することができます。
http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/idl/index.html

RMIプログラミングモデル

CORBAとは別に、もともとJavaに存在していたRMIのプログラミング方式でCORBAのサービスを開発できます。RMIで通常使われるJRMPプロトコルに代わり、CORBAとの相互運用可能なIIOPプロトコルで通信させるための規格としてRMI-IIOPというものが定められています。このモデルだとJava言語でRMI準拠のリモートインターフェースを作成しておけば、他言語で呼び出し可能なIDLを自動生成することが可能です。現在のPOJOサービスからWSDL自動生成というのに比べると面倒ですが、Java言語の範囲で透過的にCORBA通信ができるため、Java IDLのモデルよりはるかに簡単です。ちなみに、EJBのリモートインターフェースはRMI-IIOPを使っているため、CORBAのクライアントから呼び出すことが可能です。

両プログラミングモデルの使い分け

RMIプログラミングモデルはより簡単ですが、IDLを自動生成するという流れでありインターフェースに対して制約があります。したがって、レガシーなCORBAのサービスがすでに存在しており、それに対してラッピングを含めて一切手を加えることができないのであれば、採用することはできません。その場合は既存のサービスのIDLを使ってクライアントスタブを生成し、呼び出すような流れ、つまり、IDLモデルを使って呼び出すしかないようです。一方、Javaでサービスを実装し、別言語のCORBAクライアントから呼び出させる場合には通常RMI-IIOPを使うと便利と思われます。(Java EE環境ならEJBを使うべき?)
Java IDL vs. RMI-IIOP (OCMJEA forum at Coderanch)

Spring FrameworkのCORBAサポート

Spring Remotingの一部として、RMI-IIOPを使ってPOJOクラスをCORBAサービスとして公開したり、逆にクライアント側でインジェクションして呼び出すことがサポートされています。そのためには以下のクラスを使います。

  • org.springframework.remoting.rmi.JndiRmiServiceExporter(サービス側)
  • org.springframework.remoting.rmi.JndiRmiProxyFactoryBean(クライアント側)

なお、Java IDLを使ったIDLプログラミングモデルについては、残念ながら標準機能としてはサポートしていないようです。 ただ、
http://people.yandex-team.ru/~stepancheg/spring-corba/
のようなサードパーティーライブラリーが使えるかもしれません。

*1:非標準ながら、RubyPHPVisual Basicなどのサポートも行う実装もあるらしい。