Oracle® Fusion Middleware Oracle WebLogic Server RMIのプログラミング 11gリリース1 (10.3.6) B61626-04 |
|
前 |
次 |
この章では、メソッドは含まないが、すべてのリモート・オブジェクトの基礎的要素であるjava.rmi.Remote
インタフェースについて説明します。この「タグ付け」インタフェースを拡張し(リモート・クラスを識別するタグとして機能するように)、リモート・オブジェクトの構造を作成するメソッド・スタブを使って、使用するリモート・インタフェースを作成します。次に、リモート・クラスを使ってリモート・インタフェースを実装します。この実装はレジストリ内の名前にバインドされ、クライアントやサーバーはそこからオブジェクトをルックアップしてリモートで使用できます。
すでにRMIクラスを記述している場合は、リモート・インタフェースとそれを拡張するクラスでimport文を変えるだけでWebLogic RMIをインストールできます。クライアント・アプリケーションにリモート呼出しを追加するには、レジストリ内でオブジェクトを名前でルックアップします。Weblogic RMI例外はjava.rmi
例外と同じ機能を備えているので、既存のインタフェースと実装で例外の処理方法を変える必要がありません。
以下の節ではWebLogic Server RMIの実装方法について説明します。
独自のWebLogic RMIクラスを簡単な手順で記述できます。次に、その単純な例を示します。
リモートで呼び出せるすべてのクラスは、リモート・インタフェースを実装します。Javaコードのテキスト・エディタを使用し、以下のガイドラインに従ってリモート・インタフェースを記述します。
リモート・インタフェースは、java.rmi.Remoteインタフェースを拡張する必要がありますが、これにはメソッド・シグネチャは含まれません。インタフェースを実装する各リモート・クラスで実装されるメソッド・シグネチャを含めます。インタフェースの記述方法については、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は、型さえ正しければ、そのほかはインタフェースを実装するクラスに依存しない動的プロキシと動的に生成されるバイトコードもサポートします。クラスが単一のリモート・インタフェースを実装する場合、コンパイラが生成したプロキシとバイトコードは、リモート・インタフェースと同じ名前になります。クラスが複数のリモート・インタフェースを実装する場合、コンパイルから生じたプロキシとバイトコードの名前は、コンパイラが使用する名前マングリングによって決まります。
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) { // Not needed with WebLogic RMI // System.setSecurityManager(new RmiSecurityManager()); // But if you include this line of code, you should make // it conditional, as shown here: // 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にインストールしないでください。
javac
または他のJavaコンパイラを使用して.java
ファイルをコンパイルし、リモート・インタフェースとそれを実装するクラス用の.class
ファイルを作成します。
リモート・クラスに対して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コンパイラのオプションを参照してください。
リモート・クラス、リモート・クラスが実装するインタフェース、およびそのプロキシとバイトコードをコンパイルしてWebLogic Serverにインストールしたら、Javaコードのテキスト・エディタを使用し、WebLogicクライアント・アプリケーションにコードを追加してリモート・クラスのメソッドを呼び出すことができます。
通常、リモート・オブジェクトへの参照を取得するには、コードを1行だけ記述します。これは、Naming.lookup()
メソッドで行います。次に、上の例で作成したオブジェクトを使用する短いWebLogicクライアント・アプリケーションの例を示します。
package mypackage.myclient; import java.rmi.*; public class HelloWorld throws Exception { // Look up the remote object in the // WebLogic's registry Hello hi = (Hello)Naming.lookup("HelloRemoteWorld"); // Invoke a method remotely String message = hi.sayHello(); System.out.println(message); }
この例では、クライアントとしてJavaアプリケーションを使用しています。
次に、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 // Don't need this in WebLogic RMI: // extends 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(); } } }