[RMI]UnicastRemoteObject.exportObjectで毎回例外が出る
RMIサーバ/クライアントを実験しているのですが、JDK5.0にて
http://72.5.124.55/j2se/1.5.0/ja/docs/ja/guide/rmi/socketfactory/index.html
や
http://d.hatena.ne.jp/nowokay/20060112
にあるように、
(1)リモートオブジェクトを new
(2)UnicastRemoteObject.exportObject()
(3)LocateRegistry.createRegistry()
(4)(3)で起動した rmiregistry に bind
しようとしたのですが、(3)(4)にたどり着くまでもなく、
(2)で必ず例外(ExportException: object already exported)が出てしまいます。
具体的には以下のようなコードが私の環境では例外になってしまいます。
(便宜上内部クラスとして記述し直しています。また空白を全角にしています)
===================================================================
package test;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class Server {
public static void main(String[] args) throws Exception {
Server server = new Server();
server.init();
}
public void init() throws Exception {
Foo rmiObj = new FooImpl();
Foo stub = (Foo) UnicastRemoteObject.exportObject(rmiObj, 41199); //★ここで例外
LocateRegistry.createRegistry(1099);
Registry registry = LocateRegistry.getRegistry(1099);
registry.rebind("fooService", stub);
}
/* リモートインターフェース */
public interface Foo extends Remote {
public void hello() throws RemoteException;
}
public class FooImpl extends UnicastRemoteObject implements Foo {
public FooImpl() throws RemoteException {}
public void hello() throws RemoteException {
System.out.println("Hello World.");
}
}
}
===============================================================
★例外
Exception in thread "main" java.rmi.server.ExportException: object already exported
at sun.rmi.transport.ObjectTable.putTarget(ObjectTable.java:172)
at sun.rmi.transport.Transport.exportObject(Transport.java:75)
at sun.rmi.transport.tcp.TCPTransport.exportObject(TCPTransport.java:196)
at sun.rmi.transport.tcp.TCPEndpoint.exportObject(TCPEndpoint.java:382)
at sun.rmi.transport.LiveRef.exportObject(LiveRef.java:116)
at sun.rmi.server.UnicastServerRef.exportObject(UnicastServerRef.java:180)
at java.rmi.server.UnicastRemoteObject.exportObject(UnicastRemoteObject.java:293)
at java.rmi.server.UnicastRemoteObject.exportObject(UnicastRemoteObject.java:235)
at test.Server.init(Server.java:18)
at test.Server.main(Server.java:13)
===============================================================
init の2行目、つまり実質 new して exportObject しようと
するだけで例外になってしまうので、原因がよく分かりません。
他プロセスに起動したものが残っていたりしないか確認しましたが、
特に見受けられませんでした。
実はそのまさに2行目を抜いた状態で RMI サーバを起動しておき、
リモートオブジェクトを取ると…うまく取れてしまいました。
(ただし RMI サーバ/クライアントはともに同じローカル)
が、上で挙げた情報先にあるような書き方でできないのがどうにも
気持ち悪いのです。
どこが悪いのでしょうか…
補足
アドバイスありがとうございます。質問の意図としては、少し違います。 例えば、複数のサーバで同一のリモートサーバ(注:ここでの同一とは、モジュールとして同一という意味)を起動するとします。 話を簡単にするため、下記の項目をルール化します。 ・起動するサーバはhost01~09の9台のうちどれかとする ・公開ポートは一律1414とする ・サービス名は各サーバごとに任意に設定可能とする この状況で、クライアントアプリケーション側で下記のような処理はできるか?というのがこの質問の意図です。 <クライアントで実施したい処理> リモートサーバが起動している可能性があるホスト情報(host01~09)とリモートサーバ側のアクセスポート(1414)情報を利用して現在利用可能なサービスを取得し、サービス情報(ホスト・Port・サービス名情報)を GUIまたはコンソール上に表示させる。