1

タイプ のオブジェクトをエクスポートする RMI サーバーが localhost で実行されていますMessage

try {
    MessageServer obj = new MessageServer();
    Message stub = (Message) UnicastRemoteObject.exportObject(obj, 0);
    Registry registry = LocateRegistry.getRegistry();
    registry.bind("M", stub);
} catch (RemoteException e) {
} catch (AlreadyBoundException e) {
}

次に、クライアントを起動して、このオブジェクトのスタブを取得します。レジストリが見つかったようですが、tryブロックで aNotBoundExceptionがスローされます。

java.rmi.NotBoundException: M at sun.rmi.registry.RegistryImpl.lookup(RegistryImpl.java:136) at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source) at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef) .java:409) で sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267) で sun.rmi.transport.Transport$1.run(Transport.java:177) で java.security.AccessController.doPrivileged(Nativeメソッド) で、sun.rmi.transport.Transport.serviceCall(Transport.java:173) で、sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553) で、sun.rmi.transport.tcp.TCPTransport$ConnectionHandler で.run0(TCPTransport.java:808) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) で java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) で java.lang.Thread.run(Thread.java:679) で sun.rmi.transport.StreamRemoteCall .exceptionReceivedFromServer(StreamRemoteCall.java:273) の sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:251) の sun.rmi.server.UnicastRef.invoke(UnicastRef.java:377) の sun.rmi.registry. rmitest.MessageClient.main(MessageClient.java:23) の RegistryImpl_Stub.lookup(不明なソース)executeCall(StreamRemoteCall.java:251) で sun.rmi.server.UnicastRef.invoke(UnicastRef.java:377) で sun.rmi.registry.RegistryImpl_Stub.lookup(不明なソース) で rmitest.MessageClient.main(MessageClient.java: 23)executeCall(StreamRemoteCall.java:251) で sun.rmi.server.UnicastRef.invoke(UnicastRef.java:377) で sun.rmi.registry.RegistryImpl_Stub.lookup(不明なソース) で rmitest.MessageClient.main(MessageClient.java: 23)

public static void main(String args[]) {
        //String host = "localhost";
        Registry registry;
        Message stub = null;
        try {
            registry = LocateRegistry.getRegistry();
            stub = (Message) registry.lookup("M"); //NotBoundException thrown here
        } catch (NotBoundException ex) {
        } catch (AccessException ex) {
        } catch (RemoteException ex) {
        }
        try {
            stub.insert("TestString"); //NullPointerException here
        } catch (RemoteException ex) {
        }

}

なぜ"M"見つからないのですか?サーバーとクライアントの両方が Netbeans 内で起動され、レジストリは事前にターミナル経由で起動されます。

4

1 に答える 1

2

RMI は獣のようなもので、どのように実行するかが常に問題になります。

まず、@EJP が提案したように、適切な例外処理を行います。理由は、接続タイムアウトなどを取得した可能性があります。ブロックに an を入れて、e.printStackTrace()一種catchのエラー メッセージが表示されるかどうかを見てみましょう (ところで、空の作成を停止するつもりです)。catch抑制された例外を 2 日間デバッグすると、非常に迅速にブロックされます)。接続をキャッチするのはファイアウォールではありませんか?

また、 、およびに変更getRegistry()します (少し時間を節約できます)。createRegistry()bind()rebind()

発生する例外は、メイン アプリケーションが必要なサービスをバインド (登録) できず、既定のレジストリに存在しない (利用できない) ためです。

RMI はいくつかの方法で実行できます。あなたが選択したアプローチは、開発とテストでは絶対にクールですが、本番環境に置きたい場合は、いくつかの変更を行う必要があります (たとえば、rmiregistryどこかで共通の実行が行われる可能性があるため、ポリシーを使用する必要があります)。ファイルと のようないくつかのプロパティjava.rmi.codebase=...、適切なセキュリティ マネージャーをインストールする必要があるなど)。

于 2012-06-10T11:56:41.977 に答える