Why RMI registry is ignoring the java.rmi.server.c

2019-04-07 16:18发布

问题:

I am running a Hello World example for java RMI

1) I run the registry in an empty folder

motta@motta-laptop ~/tmp $ rmiregistry

2) I start the HTTP server to retrieve the classes at runtime. The download folder contains the remote interface for the client-server

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

3) I start the server passing the java.rmi.server.codebase property as suggested in the java RMI tutorial

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

The RMI registry is not contacting the HTTP server and is throwing an exception (see details after the question). But if I do the following

1) Start the rmi registry with the java.rmi.server.codebase property

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

2) Start the HTTP server as before

3) Start the server without any option

motta@motta-laptop ~/server $ java WarehouseServer

it works, but why? It seems that with the first procedure the RMI registry is ignoring the java.rmi.server.codebase property

Thank you

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

I am running

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)

The exception from the RMI registry

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)

回答1:

It seems that with the first procedure the RMI registry is ignoring the java.rmi.server.codebase property.

That's correct. The reason is that, as of JDK 7u21, the java.rmi.server.useCodebaseOnly property is true by default, whereas in prior releases it was false by default.

When useCodebaseOnly is false, the RMI Registry (and RMI clients) use the codebase that has been passed to them from the server. Now that the default value is true the registry and clients ignore the server's codebase property. The registry and clients must either set their own codebase property to match that of the server, or (not recommended) they could set useCodebaseOnly back to false. See RMI Enhancements in JDK 7 for further details.

The RMI Tutorial hasn't been updated to reflect this change. Sorry about that. I'll make sure it gets updated.