7

我正在运行 java RMI 的 Hello World 示例

1)我在一个空文件夹中运行注册表

motta@motta-laptop ~/tmp $ rmiregistry

2) 我启动 HTTP 服务器以在运行时检索类。下载文件夹包含客户端-服务器的远程接口

motta@motta-laptop ~/download $ java NanoHTTPD 8080

3)我启动服务器传递 java.rmi.server.codebase 属性,如 java RMI 教程中所建议的那样

motta@motta-laptop ~/server $ java -Djava.rmi.server.codebase="http://localhost:8080" WarehouseServer

RMI 注册表没有联系 HTTP 服务器并且正在引发异常(请参阅问题后的详细​​信息)。 但是,如果我执行以下操作

1) 使用 java.rmi.server.codebase 属性启动 rmi 注册表

motta@motta-laptop ~/tmp $ rmiregistry -J-Djava.rmi.server.codebase="http://localhost:8080/"

2)像以前一样启动HTTP服务器

3)不带任何选项启动服务器

motta@motta-laptop ~/server $ java WarehouseServer

它有效,但为什么呢?似乎在第一个过程中,RMI 注册表忽略了 java.rmi.server.codebase 属性

谢谢

==================================

我在跑步

java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)

RMI 注册表的异常

Constructing server implementation...
Binding server implementation to registry...
Exception in thread "main" java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
java.lang.ClassNotFoundException: Warehouse
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:419)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267)
at sun.rmi.transport.Transport$1.run(Transport.java:177)
at sun.rmi.transport.Transport$1.run(Transport.java:174)
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:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
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.bind(Unknown Source)
at WarehouseServer.main(WarehouseServer.java:14)
4

1 回答 1

14

似乎在第一个过程中,RMI 注册表忽略了该java.rmi.server.codebase属性。

这是正确的。原因是,从 JDK 7u21 开始,该java.rmi.server.useCodebaseOnly属性是true默认的,而在以前的版本中,它是false默认的。

useCodebaseOnly什么时候false,RMI 注册表(和 RMI 客户端)使用从服务器传递给它们的代码库。现在默认值是true注册表,客户端忽略服务器的代码库属性。注册表和客户端必须设置自己的代码库属性以匹配服务器的属性,或者(不推荐)他们可以设置useCodebaseOnlyfalse. 有关更多详细信息,请参阅JDK 7 中的 RMI 增强

RMI 教程尚未更新以反映此更改。对于那个很抱歉。我会确保它得到更新。

于 2013-08-11T18:01:02.263 回答