RMIの入門の2回目、サーバ編です。
interfaceを書いたら、これをimplementsするサーバオブジェクト(リモートオブジェクトの実体)を書きます。サーバオブジェクトは複数のRMI用interfaceをimplementsできますし、もちろんRMIでない、通常のinterfaceもimplementsしても構いません。
サーバオブジェクトとして動作するためには、RMI用interfaceをimplementsすることに加えて、適当なリモートオブジェクトのクラスをextendsしなければなりません。通常はjava.rmi.server.UnicastRemoteObjectをextendsして作成します。例えば以下の様な感じでしょうか。
import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; public class ServerEnvironmentImpl extends UnicastRemoteObject implements ServerEnvironment { public String getJavaVersion() { return System.getProperty("java.vm.version"); } public ServerEnvironmentImpl() throws RemoteException{} }
リモートオブジェクトなのでコンストラクタがRemoteExceptionをthrowします。それ以外は普通のクラスです。ただしこれだけではクライアント側がサーバオブジェクトを見つけ出すことができません。サーバ側でリモートオブジェクトの名前をRMIレジストリに登録する必要があります。これにはjava.rmi.Namingクラスを使用します。
Namingクラスにはbind、rebind、lookup、unbind等のサービスメソッドがあります。名前の登録には通常はrebindを使います。rebindの引数にはURL形式の名前と、リモートオブジェクトを渡すようになっています。URL形式の名前とは//host:port/nameの形式です。通常のURLの形式と違い、プロトコル部分が省略されています(よくrmi:を付けている例がありますが、RMIの仕様ではつけないのが通常の形式です。つけても動くようですが)。portは省略することが多いでしょう。hostは省略すればlocalhostのことになりますが、異なるホスト間でRMIを使うならばホスト名を使用します。nameにはそのオブジェクトをあらわすような名前(interfaceの名前が良いと思いますが)をつけます。
もう一度書き直してみます。
import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; import java.rmi.Naming; import java.net.MalformedURLException; public class ServerEnvironmentImpl extends UnicastRemoteObject implements ServerEnvironment { public String getJavaVersion() { return System.getProperty("java.vm.version"); } public ServerEnvironmentImpl() throws RemoteException{} public static void main(String[] args) { try { ServerEnvironment se = new ServerEnvironmentImpl(); Naming.rebind("//localhost/ServerEnvironment", se); } catch (RemoteException e) { System.err.println(e); System.exit(1); } catch (MalformedURLException e) { System.err.println(e); System.exit(1); } } }イメージ、つかめたでしょうか。