ヘッダーをスキップ
Oracle® Fusion Middleware Oracle WebLogic Server RMI プログラマーズ ガイド
11g リリース 1 (10.3.1)
B55530-01


目次
目次

戻る
戻る
 
次へ
次へ
 

6 WebLogic RMI の実装方法

すべてのリモート オブジェクトの基本単位は java.rmi.Remote インタフェースで、これにはメソッドはありません。この「タグ付け」インタフェースを拡張し (リモート クラスを識別するタグとして機能するように)、リモート オブジェクトの構造を作成するメソッド スタブを使って、使用するリモート インタフェースを作成します。次に、リモート クラスを使ってリモート インタフェースを実装します。この実装はレジストリ内の名前にバインドされ、クライアントやサーバはそこからオブジェクトをルックアップしてリモートで使用できます。

すでに RMI クラスを記述している場合は、リモート インタフェースとそれを拡張するクラスで import 文を変えるだけで WebLogic RMI をインストールできます。クライアント アプリケーションにリモート呼び出しを追加するには、レジストリ内でオブジェクトを名前でルックアップします。Weblogic RMI 例外は java.rmi 例外と同じ機能を備えているので、既存のインタフェースと実装で例外の処理方法を変える必要がありません。

WebLogic RMI の実装の手順

以下の節では WebLogic Server RMI の実装方法について説明します。

リモートで呼び出すことができるクラスの作成

独自の WebLogic RMI クラスを簡単な手順で記述できます。次に、その単純な例を示します。

手順 1. リモート インタフェースの作成

リモートで呼び出せるすべてのクラスは、リモート インタフェースを実装します。Java コードのテキスト エディタを使用し、以下のガイドラインに従ってリモート インタフェースを記述します。

  • リモート インタフェースは、java.rmi.Remote インタフェースを拡張する必要があるが、これにはメソッド シグネチャは含まれない。インタフェースを実装する各リモート クラスで実装されるメソッド シグネチャを含めます。インタフェースの作成方法については、Sun Microsystems JavaSoft チュートリアルの「Creating Interfaces」を参照してください。

  • リモート インタフェースはパブリックでなければならない。パブリックでない場合、クライアントはリモート インタフェースを実装するリモート オブジェクトをロードしようとするとエラーを受け取ります。

  • JavaSoft の RMI とは異なり、インタフェース内の各メソッドがその throws ブロックで java.rmi.RemoteException を宣言する必要はない。アプリケーションが送出する例外は、アプリケーション固有の例外である可能性があり、RuntimeException. WebLogic RMI subclasses java.rmi.RemoteException を拡張する場合があります。したがって、すでに RMI クラスがある場合、例外処理を変更する必要はありません。

  • リモート インタフェースにはコードがあまり記述されていない場合もある。必要なのは、リモート クラスで実装するメソッドのメソッド シグネチャだけです。

    以下の例に、メソッド シグネチャ sayHello() を持つリモート インタフェースを示します。

    package examples.rmi.multihello;
    import java.rmi.*;
    public interface Hello extends java.rmi.Remote {
      String sayHello() throws RemoteException;
    }
    

    JavaSoft の RMI では、リモート インタフェースを実装するすべてのクラスには、コンパイル済みのプロキシが存在しなければなりません。WebLogic RMI は、柔軟性の高い実行時のコード生成をサポートします。つまり、WebLogic RMI は、型さえ正しければ、そのほかはインタフェースを実装するクラスに依存しない動的プロキシと動的に生成されるバイトコードもサポートします。クラスが 1 つのリモート インタフェースを実装する場合、コンパイラが生成したプロキシとバイトコードは、リモート インタフェースと同じ名前になります。クラスが複数のリモート インタフェースを実装する場合、コード生成の結果できるプロキシとバイトコードの名前は、コンパイラが使う名前の区切り方によって変わります。

手順 2. リモート インタフェースの実装

Java コードのテキスト エディタを使用して、リモートで呼び出されるクラスを記述します。このクラスは、手順 1 で記述したリモート インタフェースを実装する必要があります。これは、インタフェースに含まれるメソッド シグネチャを実装することを意味します。現在のリリースでは、WebLogic RMI で行われるコード生成はこのクラス ファイルに依存します。

Weblogic RMI では、クラスは JavaSoft RMI で必須の UnicastRemoteObject を拡張する必要はありません(UnicastRemoteObject を拡張することはできますが、必須ではありません)。これにより、アプリケーションに適用しやすいクラス階層を維持できます。


注意 :

WebLogic Server では、Weblogic RMI と標準の JDK RMI の両方を使用できます。WebLogic RMI を使用する場合は、rmic コンパイラとして java weblogic.rmic ... を使用する必要があり、RMI 実装を java.rmi.server.UnicastRemoteObject のサブクラスとして作成してはなりません。標準の JDK RMI を使用する場合は、rmic コンパイラとして %JAVA_HOME%\bin\rmic を使用し、RMI 実装クラスを java.rmi.server.UnicastRemoteObject のサブクラスとして作成する必要があります。

クラスは、複数のリモート インタフェースを実装できます。また、クラスにはリモート インタフェースにないメソッドも定義できますが、このようなメソッドはリモートで呼び出せません。

次の例では、複数の HelloImpls を作成するクラスを実装し、それぞれをレジストリ内のユニークな名前にバインドします。メソッド sayHello() は、ユーザに「Hello」とあいさつし、リモートで呼び出されたオブジェクトを識別します。

package examples.rmi.multihello;
import java.rmi.*;
public class HelloImpl implements Hello {
  private String name;
  public HelloImpl(String s) throws RemoteException {
    name = s;
  }
  public String sayHello() throws RemoteException {
    return "Hello! From " + name;
  }

次に、リモート オブジェクトのインスタンスを作成する main() メソッドを記述し、それを名前 (オブジェクトの実装を指し示す URL) にバインドすることによって WebLogic RMI のレジストリに登録します。リモートでオブジェクトを使用するためにプロキシを取得しようとするクライアントは、オブジェクトを名前でルックアップできます。

次に、HelloImpl クラス用の main() メソッドの例を示します。この例では、WebLogic Server レジストリに HelloRemoteWorld という名前で HelloImpl オブジェクトを登録します。

  public static void main(String[] argv) {
    // 以下のコードは WebLogic RMI では不要
    // System.setSecurityManager(new RmiSecurityManager());
    // しかし、このコードを含める場合には、以下のように
    // 条件文にする必要がある
    // if (System.getSecurityManager() == null)
    //   System.setSecurityManager(new RmiSecurityManager());
    int i = 0;
    try {
      for (i = 0; i < 10; i++) {
        HelloImpl obj = new HelloImpl("MultiHelloServer" + i);
        Context.rebind("//localhost/MultiHelloServer" + i, obj);
System.out.println("MultiHelloServer" + i + " created.");
      }
      System.out.println("Created and registered " + i +
                         " MultiHelloImpls.");
    }
    catch (Exception e) {
      System.out.println("HelloImpl error: " + e.getMessage());
      e.printStackTrace();
    }
  }

WebLogic RMI では、アプリケーションにセキュリティを統合するためにセキュリティ マネージャを設定する必要はありません。セキュリティは、WebLogic の SSL と ACL のサポートによって処理されます。必要な場合は独自のセキュリティ マネージャを使うこともできますが、それを WebLogic Server にインストールしないでください。

手順 3. Java クラスのコンパイル

javac または他の Java コンパイラを使用して .java ファイルをコンパイルし、リモート インタフェースとそれを実装するクラス用の .class ファイルを作成します。

手順 4. 実装クラスの RMI コンパイラでのコンパイル

リモート クラスに対して WebLogic RMI コンパイラ (weblogic.rmic) を実行し、動的プロキシとバイトコードを動的に生成します。プロキシは、リモート オブジェクト用のクライアントサイド プロキシで、個々の WebLogic RMI 呼び出しを対応するサーバサイド バイトコードに転送します。サーバサイド バイトコードは、その呼び出しを実際のリモート オブジェクトの実装に転送します。weblogic.rmic を実行するには、次のコマンド パターンを使用します。

  $ java weblogic.rmic nameOfRemoteClass

nameOfRemoteClass は、$ java weblogic.rmic examples.rmi.hello.HelloImpl の完全パッケージ名を表します。

スタブまたはスケルトン クラスを作成するときに生成されたソースを保持する場合は、weblogic.rmic の実行時に -keepgenerated フラグを設定します。使用可能なコマンドライン オプションの一覧については、WebLogic RMI コンパイラのオプションを参照してください。

手順 5 : リモート メソッドを呼び出すコードの記述

リモート クラス、リモート クラスが実装するインタフェース、およびそのプロキシとバイトコードをコンパイルして WebLogic Server にインストールしたら、Java コードのテキスト エディタを使用し、WebLogic クライアント アプリケーションにコードを追加してリモート クラスのメソッドを呼び出すことができます。

通常、リモート オブジェクトへの参照を取得するには、コードを 1 行だけ記述します。これは、Naming.lookup() メソッドで行います。次に、上の例で作成したオブジェクトを使用する短い WebLogic クライアント アプリケーションの例を示します。

package mypackage.myclient;
import java.rmi.*;

public class HelloWorld throws Exception {

  // WebLogic のレジストリ内の
  // リモート オブジェクトをルックアップする
  Hello hi = (Hello)Naming.lookup("HelloRemoteWorld");
  // メソッドをリモートで呼び出す
  String message = hi.sayHello();
  System.out.println(message);
}

この例では、クライアントとして Java アプリケーションを使用しています。

Hello サンプル コード

次に、Hello インタフェースの完全なコードを示します。

package examples.rmi.hello;
import java.rmi.*;

public interface Hello extends java.rmi.Remote {

  String sayHello() throws RemoteException;

}
次に、このインタフェースを実装する HelloImpl クラスの完全なコードを示します。 
package examples.rmi.hello;

import java.rmi.*;

public class HelloImpl
    // 以下は WebLogic RMI では不要
    // UnicastRemoteObject を拡張する
    implements Hello {

  public HelloImpl() throws RemoteException {
    super();
  }

  public String sayHello() throws RemoteException {
    return "Hello Remote World!!";
  }

  public static void main(String[] argv) {
    try {
      HelloImpl obj = new HelloImpl();
      Naming.bind("HelloRemoteWorld", obj);
    }
    catch (Exception e) {
      System.out.println("HelloImpl error: " + e.getMessage());
      e.printStackTrace();
    }
  }
}