JavaRMI入門
1. 概要
2つのJVMが通信する必要がある場合、JavaRMIはそれを実現するための1つのオプションです。 この記事では、JavaRMIテクノロジーを紹介する簡単な例をブートストラップします。
2. サーバーの作成
RMIサーバーを作成するには、次の2つの手順が必要です。
- クライアント/サーバーコントラクトを定義するインターフェイスを作成します。
- そのインターフェースの実装を作成します。
2.1. 契約の定義
まず、リモートオブジェクトのインターフェイスを作成しましょう。 このインターフェースは、java.rmi.Remoteマーカーインターフェースを拡張します。
さらに、インターフェースで宣言された各メソッドは、java.rmi。RemoteExceptionをスローします。
public interface MessengerService extends Remote {
String sendMessage(String clientMessage) throws RemoteException;
}
ただし、Javaタイプが java.io.Serializabl e を実装している限り、RMIはメソッドシグネチャの完全なJava仕様をサポートしていることに注意してください。
今後のセクションで、クライアントとサーバーの両方がこのインターフェイスをどのように使用するかを説明します。
サーバーの場合、リモートオブジェクトと呼ばれることが多い実装を作成します。
クライアントの場合、RMIライブラリはスタブと呼ばれる実装を動的に作成します。
2.2. 実装
さらに、リモートオブジェクトと呼ばれるリモートインターフェイスを実装しましょう。
public class MessengerServiceImpl implements MessengerService {
@Override
public String sendMessage(String clientMessage) {
return "Client Message".equals(clientMessage) ? "Server Message" : null;
}
public String unexposedMethod() { /* code */ }
}
メソッド定義からthrows RemoteException句を省略していることに注意してください。
リモートオブジェクトがRemoteExceptionをスローすることはまれです。これは、この例外は通常、クライアントへの通信エラーを発生させるためにRMIライブラリ用に予約されているためです。
それを除外すると、実装をRMIに依存しないという利点もあります。
また、リモートオブジェクトで定義されているがインターフェイスでは定義されていない追加のメソッドは、クライアントには表示されません。
3. サービスの登録
リモート実装を作成したら、リモートオブジェクトをRMIレジストリにバインドする必要があります。
3.1. スタブの作成
まず、リモートオブジェクトのスタブを作成する必要があります。
MessengerService server = new MessengerServiceImpl();
MessengerService stub = (MessengerService) UnicastRemoteObject
.exportObject((MessengerService) server, 0);
静的UnicastRemoteObject.exportObjectメソッドを使用して、スタブ実装を作成します。 スタブは、基盤となるRMIプロトコルを介してサーバーと通信する魔法を実行します。
exportObject の最初の引数は、リモートサーバーオブジェクトです。
2番目の引数は、exportObjectがリモートオブジェクトをレジストリにエクスポートするために使用するポートです。
ゼロの値を指定することは、 exportObject が使用するポートを気にしないことを示します。これは一般的であり、動的に選択されます。
残念ながら、ポート番号のない exportObject()メソッドは非推奨になりました。
3.2. レジストリの作成
サーバーのローカルにあるレジストリを立ち上げることも、別のスタンドアロンサービスとして立ち上げることもできます。
簡単にするために、サーバーに対してローカルなものを作成します。
Registry registry = LocateRegistry.createRegistry(1099);
これにより、サーバーがスタブをバインドし、クライアントが検出できるレジストリが作成されます。
また、サーバーに対してローカルにレジストリを作成しているため、createRegistryメソッドを使用しました。
デフォルトでは、RMIレジストリはポート1099で実行されます。 むしろ、createRegistryファクトリメソッドで別のポートを指定することもできます。
ただし、スタンドアロンの場合は、 getRegistry を呼び出し、ホスト名とポート番号をパラメーターとして渡します。
3.3. スタブのバインド
したがって、スタブをレジストリにバインドしましょう。 RMIレジストリは、JNDIなどのような命名機能です。 ここでも同様のパターンに従い、スタブを一意のキーにバインドできます。
registry.rebind("MessengerService", stub);
その結果、レジストリを見つけることができるすべてのクライアントがリモートオブジェクトを使用できるようになりました。
4. クライアントの作成
最後に、リモートメソッドを呼び出すクライアントを作成しましょう。
これを行うには、最初にRMIレジストリを見つけます。 さらに、制限付きの一意キーを使用してリモートオブジェクトスタブを検索します。
最後に、sendMessageメソッドを呼び出します。
Registry registry = LocateRegistry.getRegistry();
MessengerService server = (MessengerService) registry
.lookup("MessengerService");
String responseMessage = server.sendMessage("Client Message");
String expectedMessage = "Server Message";
assertEquals(expectedMessage, responseMessage);
ローカルマシンとデフォルトポート1099でRMIレジストリを実行しているため、getRegistryにパラメータを渡しません。
実際、レジストリが別のホストまたは別のポートにある場合は、これらのパラメータを指定できます。
レジストリを使用してスタブオブジェクトを検索すると、リモートサーバーでメソッドを呼び出すことができます。
5. 結論
このチュートリアルでは、Java RMIの概要と、JavaRMIがクライアントサーバーアプリケーションの基盤となる方法について説明しました。 RMIのユニークな機能のいくつかに関する追加の投稿をお楽しみに!
このチュートリアルのソースコードは、GitHubのにあります。