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)
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.