我有一个在本地主机上运行的 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) {
}
然后我想启动一个客户端并获取该对象的 stub 。似乎找到了注册表,但随后在 try
block 中抛出了 NotBoundException
:
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) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267) at sun.rmi.transport.Transport$1.run(Transport.java:177) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:173) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:679) at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:273) at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:251) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:377) at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source) at 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内部启动,注册表预先通过终端启动。
最佳答案
RMI 有点像野兽,如何运行它始终是一个问题。
首先,按照 @EJP 建议进行适当的异常处理:原因可能是连接超时或类似的情况 - 因此将 e.printStackTrace()
放入 catch 中
block ,让我们看看是否收到某种错误消息(顺便说一句,当您调试受抑制的异常 2 天时,您将很快停止创建空的 catch
block )。难道你的防火墙不能捕获连接吗?
我还将 getRegistry()
更改为 createRegistry()
,将 bind()
更改为 rebind()
(它可以节省您一些时间)。
您遇到的异常是因为您的主应用程序无法绑定(bind)(注册)您想要的服务,并且默认注册表中缺少该服务(不可用)。
RMI 可以通过多种方式完成。您选择的方法对于开发和测试来说绝对很酷,但是如果您想将其投入生产,则需要进行一些更改(例如,可能会有一个通用的rmiregistry
在某处运行,您必须使用策略文件和一些属性,例如 java.rmi.codebase=...
,您需要安装适当的安全管理器等)
关于java - 本地主机上的 NotBoundException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10962933/