このドキュメントは、CORBA によってサポートされている任意の言語で記述されたクライアントから Enterprise JavaBeansTM コンポーネント (以下「EJBTM コンポーネント」) にアクセスできるようにする方法を説明します。このドキュメントは、JavaTM 2 Platform, Enterprise Edition (以下「J2EETM」) および CORBA (Common Object Request Broker Architecture) に関する高度な知識をお持ちのプログラマを対象に書かれています。  
J2EE テクノロジは、エンタープライズアプリケーションを単純化します。J2EE テクノロジにより、エンタープライズアプリケーションは、Enterprise JavaBeansTM (EJBTM) に基づいたモジュール型の再利用可能な標準コンポーネントに準拠するようになり、J2EE テクノロジから提供された完全なサービスセットを利用できるようになります。アプリケーションの細かい動作の多くは、J2EE テクノロジによって自動的に処理されます。時間のかかる複雑なアプリケーション開発処理が自動化されるため、エンタープライズ開発者は、インフラストラクチャーの構築よりもビジネスロジックの拡張に力を注ぐことができます。 
EJBTM のサーバー側コンポーネントモデルを使うと、トランザクションに適した、拡張性と移植性の高いミドルウェアコンポーネントを簡単に開発できます。Enterprise JavaBeans サーバーを使用することで、トランザクション、セキュリティー、データベース接続性などのミドルウェアサービスが自動的にサポートされるため、ミドルウェア開発の複雑さが軽減されます。 
CORBA は、オブジェクト管理グループ (OMG) の規格の 1 つです。ベンダーに依存しないオープンなアーキテクチャーと、複数のコンピュータアプリケーションがネットワーク経由で利用できるインフラストラクチャーという特徴を備えています。CORBA ベースのプログラムは、標準プロトコルである IIOP (Internet Inter-ORB Protocol) を使って、ほかの CORBA ベースのプログラムと連携できます。このとき、双方のプログラムの作成元ベンダーは同じでも異なっていてもかまいません。これらのプログラムが利用するコンピュータ、オペレーティングシステム、プログラミング言語、ネットワークについても、ほとんど制限はありません。CORBA の詳細については、http://www.omg.org/gettingstarted/gettingstartedindex.htm を参照してください。 
CORBA テクノロジは分散オブジェクトフレームワーク、そのフレームワークをサポートするサービス、および他言語との相互運用性を提供して Java プラットフォームを補完します。CORBA テクノロジは、Java 2 プラットフォームの重要な部分であり、Enterprise JavaBeans コンポーネント、標準プロトコル Internet Inter-ORB Protocol (「Java RMI-IIOP」) を利用して実行されている Java Remote Method Invocation API、および Java IDL API (「Java IDL」) で使用されます。 
OMG Interface Definition Language (IDL) は、リモートオブジェクトによって実装されるインタフェースの説明に使用されます。IDL は、インタフェース名と個々の属性およびメソッドの名前の定義に使用されます。IDL ファイルの作成後、IDL コンパイラを使ってクライアントスタブとサーバースケルトンを生成できます。OMG で言語マッピングの仕様が定義されている言語であれば、どの言語でも使用できます。OMG IDL の詳細については、http://www.omg.org/gettingstarted/omg_idl.htm を参照してください。 
Java IDL は、業界標準の OMG IDL およびオブジェクト管理グループ (http://www.omg.org) によって定義された IIOP を使用して、分散 Java アプリケーションからリモートネットワークサービスを透過的に処理できるようにします。Java RMI over IIOP API は、 
EJB コンポーネントのプログラミングを行う開発者は、分散オブジェクトモデルとして Java RMI プログラミングモデルを使用します。このプログラミングモデルでは、Java RMI-IIOP がすべてのアプリケーションサーバーに共通の必須トランスポートプロトコルになります。異機種サーバー混在環境では、EJB アーキテクチャーと CORBA の標準マッピングにより、次のような相互運用性が実現されます。 
このドキュメントの残りの部分では、エンタープライズ Bean オブジェクトにアクセスする CORBA クライアントアプリケーションの例を紹介します。このドキュメントでは、Java プログラミング言語、C++、C、Smalltalk、COBOL、Ada、Lisp、または Python を含む任意の CORBA サポート言語で記述されたクライアントアプリケーションを「CORBA クライアント」と呼びます。以下の例の Java コードはエンタープライズ Bean 固有のコードですが、Java RMI-IIOP API を使って作成されたサーバーにアクセスする CORBA クライアントの開発プロセスは共通です。 
J2EE テクノロジを実装するその他のベンダーが提供する類似アプリケーションへのリンクは、「同様のその他の例へのリンク」で確認できます。 
以下は、EJB コンポーネントにアクセスする CORBA クライアントアプリケーションの開発例です。この例のクライアントは C++ プログラミング言語で記述されていますが、実際には、CORBA によってサポートされている言語であればどの言語を使用してもかまいません。 
以下の節では、エンタープライズ Bean にアクセスできる CORBA クライアントの一般的な開発プロセスを紹介します。 
例を単純化するため、一部の説明を省略しています。より高度なソリューションの構築方法については、「複雑なインタフェースの使用上のヒント」を参照してください。
 
以下は、Java RMI-IIOP および CORBA クライアントからアプリケーションサーバーに送信された単純な  
 
 
 
  これらのコマンドは、現在のディレクトリ内にすべての  
この節では、前の節で生成した Java クラスファイルからインタフェース定義言語 (IDL) ファイルを生成する方法を説明します。以下の例では、Java コードを IDL にマッピングする際、 
この例では、 
上の例の  
Java クラスファイルに対して  
注:CORBA 例外は継承をサポートしないため、Java 言語と IDL のマッピングにより、実際の Java 例外に相当する CORBA 値型を含む  
 
クライアントアプリケーションは、CORBA によってサポートされている任意の言語で記述できます。次に、Object Request Broker (ORB) と  
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
これで、Logger アプリケーションと  
J2EE 1.3 リファレンス実装を使用している場合は、アプリケーションサーバー上に次のようなメッセージが表示されます。  
実行プロセスの終了手順はオペレーティングシステムによって異なります。異なったサーバーを使用している場合は、システム文書で詳細を確認してください。 
ここまでの例を使って、エンタープライズ Bean に接続する Java RMI-IIOP を簡単に開発できます。次に、C++ クライアントを使用する例との違いを挙げておきます。 
以下は、 
C++ クライアントではなく Java RMI-IIOP クライアントでアプリケーション例を実行するには、次の手順に従ってください。 
 
 J2EE RI を実行しているウィンドウに、次のメッセージが表示されます。 クライアントを実行しているウィンドウには、次のメッセージが表示されます。
 
 
 
このためには、 
インタフェースは、それぞれ異なった言語を使用するクライアントとサーバー間の通信において重要な役割を果たします。以下のヒントを参考にすることにより、この領域で成功する確率を高めることができます。 
これらの型を IDL にマッピングしたら、次にクライアントプログラミング言語に実装する必要があります。Java オブジェクトの直列化および RMI-IIOP API は、ワイヤー形式と、時間の経過とともに変化するクラスの内部表現を許可します。このため、CORBA クライアントアプリケーションと JavaTM 2 Platform, Standard Edition (J2SETM) の実装またはバージョンが非互換になる可能性があります。  
戻り値の型またはメソッドのパラメータで複雑なデータ構造を使用しなければならない場合もあります。このような場合は、IDL で開始してみてください。データ構造と例外を IDL で定義してから EJB インタフェースで使用します。これにより、逆マッピングによってユーザーの CORBA インタフェースに侵入する不正行為を阻止できます。  
たとえば、最初に IDL で  
CORBA IDL は、メソッドの多重定義をサポートしません。Java 言語と IDL のマッピングでは、メソッド名をすべての IDL パラメータ型と組み合わせるような IDL メソッド定義を作成することによって、この問題を解決します。ただし、生成されるメソッド名は、Java プログラミング言語以外の言語を使用する開発者にとってはたいへんわかりにくいものになります。  
選択肢が非常に限られている場合や、記述しようとしているコードへの影響が大きい場合は、サーバー側ブリッジを利用してみてください。ブリッジの詳しい構築方法は、リンクの節に記載されているサイトで確認できます。  
J2EE テクノロジを実装するベンダーの多くは、CORBA と Enterprise JavaBeans テクノロジを統合する優れた例とヒントを提供しています。  
 Copyright © 2002-2004 Sun Microsystems, Inc., 901 San Antonio Road, Palo Alto, California 94303, U.S.A. All rights reserved.
 本製品に組み込まれた技術に関する知的所有権は、米国 Sun Microsystems, Inc. に帰属します。これらの中には、1 個以上の米国特許 (一覧は http://www.sun.com/patents)、外国特許または特許出願により保護されているものもあります。
 本製品は、その使用、複製の頒布、逆コンパイルを制限するライセンスに基づいて配布されます。サンまたはサンに対する許諾者の書面による事前の許可なく、本製品のいかなる部分も、いかなる方法によっても複製することが禁じられます。
 フォント技術を含む第三者のソフトウェアは、著作権法によって保護されており、提供者からライセンスを受けているものです。
 Sun、Sun Microsystems、Sun のロゴ、Java Enterprise JavaBeans、EJB、J2EE、Java SE は、米国ならびにその他の国における米国 Sun Microsystems, Inc. の登録商標です。
 UNIX は、X/Open Company, Ltd が独占的にライセンスしている米国ならびに他の国における登録商標です。
 
 javax.rmi API を介した CORBA サーバーおよびアプリケーションのプログラミングを可能にします。 
Enterprise JavaBeans コンポーネントにアクセスする CORBA クライアントの開発
第 I 部:Enterprise JavaBeans コンポーネントの記述
String ログメッセージを受け付けるエンタープライズ Bean のコード例です。このエンタープライズ Bean は、受け付けたメッセージを現在のサーバー時間とともにサーバー上に出力します。/Java/src/ejbinterop ディレクトリに、Logger.java、LoggerHome.java、LoggerEJB.java、LogMessage.java の各ファイルを作成します。
Logger.java
Logger.java ファイルは、エンタープライズ Bean のリモートインタフェースとして、EJBObject オブジェクトを拡張します。リモートインタフェースは、EJB オブジェクトのリモートクライアントビューを提供し、リモートクライアントから呼び出し可能なビジネスメソッドを定義します。 
//Code Example 1: Logger.java
package ejbinterop;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
/**
 * Accepts simple String log messages and prints
 * them on the server.
 */
public interface Logger extends EJBObject
{
    /**
     * Logs the given message on the server with
     * the current server time.
     */
    void logString(String message) throws RemoteException;
}
LoggerHome.java
LoggerHome.java ファイルは、EJBHome を拡張します。EJBHome インタフェースは、すべての EJB コンポーネントのリモートホームインタフェースによって拡張される必要があります。ホームインタフェースは、リモートクライアントによる EJB オブジェクトの作成、検索、削除を可能にするメソッドと、EJB インスタンスに固有ではないホームビジネスメソッドを定義します。 
//Code Example 2: LoggerHome.java
package ejbinterop;
import java.rmi.RemoteException;
import javax.ejb.EJBHome;
import javax.ejb.CreateException;
public interface LoggerHome extends EJBHome
{
    Logger create() throws RemoteException, CreateException;
}
LoggerEJB.java
LoggerEJB.java ファイルには、セッション Bean のコードが格納されています。セッション Bean はクライアントによって作成されたエンタープライズ Bean であり、通常、1 回のクライアントサーバーセッションが終了するまで有効です。セッション Bean は、計算やデータベースアクセスなどの処理を、クライアントに代わって実行します。この例のエンタープライズ Bean は、クライアントから単純な String ログメッセージを受け付け、サーバー上に出力します。
//LoggerEJB.java
package ejbinterop;
import javax.ejb.*;
import java.util.*;
import java.rmi.*;
import java.io.*;
/**
 * Accepts simple String log messages and prints
 * them on the server.
 */
public class LoggerEJB implements SessionBean {
    public LoggerEJB() {}
    public void ejbCreate() {}
    public void ejbRemove() {}
    public void ejbActivate() {}
    public void ejbPassivate() {}
    public void setSessionContext(SessionContext sc) {}
    /**
     * Logs the given message on the server with
     * the current server time.
     */
    public void logString(String message) {
        LogMessage msg = new LogMessage(message);
        System.out.println(msg);
    }
}
LogMessage.java
LogMessage.java ファイルは、現在日時を記録し、メッセージを示す書式付きの String を作成し、このメッセージをサーバーに出力します。
//LogMessage.java
package ejbinterop;
import java.io.Serializable;
import java.util.Date;
import java.text.*;
/**
 * Simple message class that handles pretty
 * printing of log messages.
 */
public class LogMessage implements Serializable
{
    private String message;
    private long datetime;
    /**
     * Constructor taking the message. This will
     * take the current date and time.
     */
    public LogMessage(String msg) {
        message = msg;
        datetime = (new Date()).getTime();
    }
    /**
     * Creates a formatted String showing the message.
     */
    public String toString() {
        StringBuffer sbuf = new StringBuffer();
        DateFormat dformat
            = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
	DateFormat.LONG);
        FieldPosition fpos = new
            FieldPosition(DateFormat.DATE_FIELD);
        dformat.format(new Date(datetime), sbuf, fpos);
        sbuf.append(": ");
        sbuf.append(message);
        return sbuf.toString();
    }
}
javac -classpath $J2EE_HOME/lib/j2ee.jar:.. *.java
.java ファイルの class ファイルを作成します。このコマンドを始め、このドキュメントで取り上げるコマンドを利用するためには、環境変数 J2EE_HOME を正しく設定しておく必要があります。 $J2EE_HOME を使用するのは、Unix® オペレーティング環境の規約です。Microsoft Windows オペレーティング環境で作業を行う場合は、この部分を  %J2EE_HOME% で置き換えてください。
第 II 部:CORBA IDL の生成
 rmic コンパイラを使用します。IDL では、プログラミング言語に依存せずに、宣言するだけでオブジェクトの API を指定することができます。  rmic コンパイラを実行します。
rmic -idl -noValueMethods -classpath
  $J2EE_HOME/lib/j2ee.jar:<path_to_ejbinterop_dir>
  -d <path_to_where_idl_files_should_be_generated>
  ejbinterop.Logger ejbinterop.LoggerHome
 javax.ejb パッケージを定義する JAR ファイルと  ejbinterop ファイルのディレクトリを取り込んでいます。JavaTM 2 Platform, Enterprise Edition (J2EETM) version 1.3 リファレンス実装 (RI) を使用する場合、JAR ファイルは $J2EE_HOME/lib/j2ee.jar にあります。  rmic のコマンド行では、処理を高速化するため、noValueMethods オプションを使用することをお勧めします。このオプションを指定すると、 rmic は、CORBA 値型にマッピングされるパラメータまたは戻り値の型を持つメソッドをすべてスキップします。その結果、不要な IDL を生成して C++ クライアントに実装することを防げます。ただし、この方法では、パラメータまたは戻り値として、基本データ型、配列、および Strings しか使用できない (Java クラス型を使用できない) という欠点もあります。詳細については、「複雑なインタフェースの使用上のヒント」を参照してください。 rmic コンパイラを実行すると、上記の rmic 文の -d オプションで指定したディレクトリに、次のファイルが生成されます。 
java/lang/Ex.idl 
java/lang/Exception.idl 
java/lang/Object.idl 
java/lang/Throwable.idl 
java/lang/ThrowableEx.idl 
javax/ejb/CreateEx.idl 
javax/ejb/CreateException.idl 
javax/ejb/EJBHome.idl 
javax/ejb/EJBMetaData.idl 
javax/ejb/EJBObject.idl 
javax/ejb/Handle.idl 
javax/ejb/HomeHandle.idl 
jajavax/ejb/RemoveEx.idl 
javax/ejb/RemoveException.idl 
ejbinterop/Logger.idl 
ejbinterop/LoggerHome.idl 
 EJBMetaData 実装は、現在では各アプリケーションサーバーに固有です。したがって、Java プラットフォーム以外のプラットフォームで同等のものを開発し、長期間にわたって連続運用するのは困難です。これらを IDL から削除することもできますが、Java インタフェースに変更を加えるたびに削除処理を実行し、再度  rmic コンパイラを使って IDL ファイルを生成しなければならないので、非常に面倒です。
 Ex クラスが作成されます。ただし、ここで取り上げる例はごく基本的なものなので、例外のサポートまではあまり考慮しません。例外の詳細については、http://java.sun.com/javase/6/docs/technotes/guides/idl/jidlExceptions.html. を参照してください。
第 III 部:CORBA クライアントの作成
 LoggerHome の  corbaname URL を持つ単純な C++ クライアントのコードを紹介します。サーバー上の単純な  String メッセージを記録するコードです。 include 文に変更を加え、C++ ORB ベンダーのライブラリに従って値ファクトリ登録コードを修正する必要があります。この例は ORBacus for C++ 4.0.5 用であり、一部はこの製品固有の C++ コードです。corbaname URL は、ユーザーが読むことのできる形式の URL であり、CORBA オブジェクトへのアクセスを可能にします。これを使って、特定のネーミングコンテキストから文字列化された名前を取得する (名前解決を行う) ことができます。これは、CORBA Interoperable Naming Service (INS) の一部です。INS は、J2EE プラットフォームの以前のリリースで配布された CORBA Object Services (COS) の拡張です。INS の詳細については、http://java.sun.com/javase/6/docs/technotes/guides/idl/jidlNaming.html#INS. を参照してください。
corbaname URL のポイント先ネーミングコンテキストで LoggerHome オブジェクトを検索する
LoggerHome オブジェクトへ返されるオブジェクトから安全なダウンロードキャストを実行する
LoggerEJB オブジェクト参照の作成
//Code Example: Client.cpp
#include <fstream.h>
// C++ ORB Vendor specific include files
// These are from C++ ORBacus 4.0.5
#include <OB/CORBA.h>
#include <OB/OBORB.h>
// Include files generated from our IDL
#include <java/lang/Exception.h>
#include <java/lang/Throwable.h>
#include <javax/ejb/CreateException.h>
#include <javax/ejb/RemoveException.h>
#include <ejbinterop/Logger.h>
#include <ejbinterop/LoggerHome.h>
/**
 * Given an ORB and a corbaname URL for a LoggerHome
 * object, logs a simple string message on the server.
 */
void
run(CORBA::ORB_ptr orb, const char* logger_home_url)
{
  cout << "Looking for: " << logger_home_url << endl;
  // Look up the LoggerHome object in the naming context
  // pointed to by the corbaname URL
  CORBA::Object_var home_obj
    = orb->string_to_object(logger_home_url);
  // Perform a safe downcast
  ejbinterop::LoggerHome_var home
    = ejbinterop::LoggerHome::_narrow(home_obj.in());
  assert(!CORBA::is_nil(home));
  // Create a Logger EJB reference
  ejbinterop::Logger_var logger = home->create();
  CORBA::WStringValue_var msg =
    new CORBA::WStringValue((const CORBA::WChar*)L"Message
      from a C++ client");
  cout << "Logging..." << endl;
  // Log our message
  logger->logString(msg);
  // Tell the application server we won't use this
  // EJB reference any more
  logger->remove();
  cout << "Done" << endl;
}
/**
 * Simple main method that checks arguments, creates an
 * ORB, and handles exceptions.
 */
int
main(int argc, char* argv[])
{
  int exit_code = 0;
  CORBA::ORB_var orb;
  try {
  // Check the arguments
  if (argc != 2) {
    cerr << "Usage: Client <corbaname URL of LoggerHome>" << endl;
    return 1;
  }
  // Create an ORB
  orb = CORBA::ORB_init(argc, argv);
  // Register value factories
  // NOTE: This is overkill for the example since we'll never
  // get these exceptions.  Also, the _OB_id method is a
  // proprietary feature of ORBacus C++ generated code.
  CORBA::ValueFactory factory = new java::lang::Throwable_init;
  orb -> register_value_factory(java::lang::Throwable::_OB_id(),
    factory);
  factory -> _remove_ref();
  factory = new java::lang::Exception_init;
  orb -> register_value_factory(java::lang::Exception::_OB_id(),
    factory);
  factory -> _remove_ref();
  factory = new javax::ejb::CreateException_init;
  orb -> 		    register_value_factory(javax::ejb::CreateException::_OB_id(),
      factory);
  factory -> _remove_ref();
  factory = new javax::ejb::RemoveException_init;
  orb ->
    register_value_factory(javax::ejb::RemoveException::_OB_id(),
      factory);
  factory -> _remove_ref();
  // Perform the work
  run(orb, argv[1]);
} catch(const CORBA::Exception& ex) {
  // Handle any CORBA related exceptions
  cerr << ex._to_string() << endl;
  exit_code = 1;
}
  // Release any ORB resources
  if (!CORBA::is_nil(orb)) {
    try {
      orb -> destroy();
    } catch(const CORBA::Exception& ex) {
      cerr << ex._to_string() << endl;
      exit_code = 1;
    }
  }
  return exit_code;
}
 第 IV 部:Enterprise JavaBeans コンポーネントの配備
 LoggerEJB コンポーネントを配備する例です。
	$J2EE_HOME/bin/j2ee -verbose
	$J2EE_HOME/bin/deploytool
[ファイル] -> [新規] -> [アプリケーション] を選択します。
 Logger.ear と入力し、アプリケーションを作成するファイルを指定します。
 Logger と入力します。
 
[ファイル]  -> [新規]  -> [エンタープライズ] を選択します。
 ejbinterop パッケージから以下の 4 つの  .class ファイルを追加します。 Logger.class、 LoggerHome.class、 LoggerEJB.class、 LogMessage.class[了解] を選択し、[次] を選択します。
[ステートレス セッション Bean タイプ] を選択します。
[エンタープライズ Bean クラス] の ejbinterop.LoggerEJB を選択します。 
[リモート ホーム インタフェース] の ejbinterop.LoggerHome を選択します。
[リモート インタフェース] の ejbinterop.Logger を選択します。 
[セキュリティー 設定] ページが表示されるまで、[次] ボタンを繰り返し押します。
配備値 の設定] ボタンを選択します。
サポートする クライアントの 選択] を選択します。
ツール]  -> [配備] を選択します。
JNDINameアプリケーション] の LoggerEJB 名フィールドに ejbinterop/logger と入力します。
 LoggerEJB コンポーネントが配備され、メッセージを受信する準備ができました。 
第 V 部:クライアントの実行可能ファイルの実行
Client corbaname:iiop:1.2@localhost:1050#ejbinterop/logger
 Client は実行するアプリケーションの名前 corbaname は特定のネーミングコンテキストから文字列化された名前を取得することを指定  iiop:1.2 は ORB に IIOP プロトコルと GIOP 1.2 を使用するように指示 localhost。この例を応用して 2 台のマシンを実行する場合は、 localhost の位置にサーバーを実行するマシンの IP アドレスまたはホスト名を入力する1050 はネーミングサービスが要求を待機するポート。J2EE バージョン 1.3 RI では、ネーミングサービスが待機するデフォルトポートは 1050。参照部分からハッシュマークのあるポイント ( Client corbaname:iiop:1.2@localhost:1050 ) までが、ルートネーミングコンテキストを返す URL ejbinterop/logger は解決するネーミングコンテキスト内の名前
Sep 21, 2001 3:33:07 PM PDT: Message from a C++ client
 ejbinterop/
logger is the name to be resolved from the Naming Service.
第 VI 部:J2EE サーバーの停止
$J2EE_HOME/bin/j2ee -stop
Java RMI-IIOP クライアントアプリケーションの作成
クライアント Jar を返します] チェックボックスをオンにする  LoggerEJB コンポーネントの Java RMI-IIOP バージョンのクライアントのコードです。C++ クライアントの例と同じ手順に従います。クライアントの実行時は、C++ の例と同じ URL を使用します。 
//Code Example: LogClient.java
package ejbinterop;
import java.rmi.RemoteException;
import javax.rmi.*;
import java.io.*;
import javax.naming.*;
import javax.ejb.*;
/**
 * Simple Java RMI-IIOP client that uses an EJB component.
 */
public class LogClient
{
    /**
     * Given a corbaname URL for a LoggerHome,
     * log a simple String message on the server.
     */
    public static void run(String loggerHomeURL)
        throws CreateException, RemoveException,
               RemoteException, NamingException
    {
        System.out.println("Looking for: " + loggerHomeURL);
        // Create an InitialContext. This will use the
        // CosNaming provider we will specify at runtime.
        InitialContext ic = new InitialContext();
        // Lookup the LoggerHome in the naming context
        // pointed to by the corbaname URL
        Object homeObj = ic.lookup(loggerHomeURL);
        // Perform a safe downcast
        LoggerHome home
            = (LoggerHome)PortableRemoteObject.narrow(homeObj,
	LoggerHome.class);
        // Create a Logger EJB reference
        Logger logger = home.create();
        System.out.println("Logging...");
        // Log our message
        logger.logString("Message from a Java RMI-IIOP client");
        // Tell the application server we won't use this
        // EJB reference anymore
        logger.remove();
        System.out.println("Done");
    }
    /**
     * Simple main method to check arguments and handle
     * exceptions.
     */
    public static void main(String args[])
    {
        try {
            if (args.length != 1) {
                System.out.println("Args: corbaname URL of LoggerHome");
                System.exit(1);
            }
            LogClient.run(args[0]);
        } catch (Throwable t) {
            t.printStackTrace();
            System.exit(1);
        }
    }
}
Java RMI-IIOP クライアントでアプリケーションを実行
ejbinterop / ディレクトリ内の .java ファイルをコンパイルします。javac -classpath $J2EE_HOME/lib/j2ee.jar:<ejbinterop_directory> *.java
java -classpath $J2EE_HOME/lib/j2ee.jar:
<path to LoggerClient.jar>/LoggerClient.jar:
<directory_above_ejbinterop>:<ejbinterop_directory>
ejbinterop.LogClient
corbaname:iiop:1.2@localhost:1050#ejbinterop/logger 
Jan 31, 2002 2:27:47 PM PST: Message from a Java RMI-IIOP client
Looking for: corbaname:iiop:1.2@localhost:1050#ejbinterop/logger
Logging...
Done
基本アプリケーションの拡張
拡張の利点
 rmic の実行時に  -noValueMethods スイッチを省略します。さらに、IDL から C++ 言語へのマッピングコンパイラを再実行し、生成された値型がサポートされるかどうかを確認します。 Logger に LogMessage をとるメソッドを追加。 
複雑なインタフェースの使用上のヒント
 java.util 内のコレクションなど) を使用しない LogMessage クラスを定義しておき、Java 言語から IDL へのコンパイルでは、Logger EJB コンポーネントのメソッドパラメータとしてこのクラスを使用します。 
同様のその他の例へのリンク