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);
}
}
}
イメージ、つかめたでしょうか。