1

我有一个在本地主机上运行的 RMI 服务器,导出一个类型的对象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) {
}

然后我想启动一个客户端并获取这个对象的存根。似乎找到了注册表,但随后在tryNotBoundException中抛出了 a:

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) 在 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。 RegistryImpl_Stub.lookup(Unknown Source) at rmtest.MessageClient.main(MessageClient.java:23)在 sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source) 在 rmtest.MessageClient.main(MessageClient.java: 23)在 sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source) 在 rmtest.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 的建议进行适当的异常处理:原因可能是您遇到连接超时或类似情况 - 所以将 ane.printStackTrace()放入catch块中,让我们看看我们是否收到某种错误消息(顺便说一句,您将停止创建空catch当您调试一个抑制的异常 2 天时会非常快地阻塞)。不能是您的防火墙捕获了连接吗?

我也会更改getRegistry()createRegistry(), 和(它可以bind()rebind()您节省一点时间)。

您遇到的异常是因为您的主应用程序无法绑定(注册)您想要的服务,并且默认注册表中缺少(不可用)。

RMI 可以通过多种方式完成。您选择的方法对于开发和测试来说绝对很酷,但是如果您想将其投入生产,您需要进行一些更改(例如,可能会有一个共同rmiregistry运行的地方,您必须使用策略文件和一些属性,例如java.rmi.codebase=...,您需要安装适当的安全管理器等)

于 2012-06-10T11:56:41.977 回答