Why RMI registry is ignoring the java.rmi.server.codebase property
Asked Answered
B

1

8

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)
Blockage answered 27/5, 2013 at 9:4 Comment(6)
Very strange. Can you try it all again without the quotes around the codebase URL?Shop
Hi EJP, I have tried without quotes and the behavior is the sameBlockage
I am still working on that and It really looks like a bug. The above mentioned issue occurs in my Linux Mint VM, while if I run the exact same code (and configuration) on my Windows machine everything goes fine.Blockage
I confirm that in Windows I do not need to pass the codebase argument to the rmiregistry, while in Linux Mint I need it I recorded everything and setup a repository with the example and instructions to run it github.com/mottalrd/RMITutorial (Warehouse v1 set of projects)Blockage
Is it possible that in Linux you have a CLASSPATH environment variable that is set when you start the Registry and points to your server code?Shop
I have checked, the classpath is blank. I started the RMI registry both from console and using the eclipse external tools command (providing as a working directory a directory without project related classes). The behavior is the same :/Blockage
L
16

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.

Lymphoid answered 11/8, 2013 at 18:1 Comment(5)
Very, very useful answer! Thanks a lot, you saved me a lot of time! Anyway, oracle sucks with this modification. First, it has no justification (event oracle didn't bother to provide one). Second, as they write themselves: "This change of default value may cause RMI-based applications to break unexpectedly". Yes! That's the oracle we so painfully know! SUN, we miss you so much!Helsa
@wrzasa: the justification could be this vulnerability. The "other vendor" mentioned is likely this one.Foetation
The RMI Tutorial does not yet mention the useCodebaseOnly property. Every little hint there would help people getting not confused why the sample is not working - just like me. Please update the tutorial to keep the high quality there.Deponent
SIR, very sorry to inform but the RMI code has still not been updated. It seems that you forgot your commitment! @StuartMarksOmasum
Tutorial still not updated for Java 8. I just got it to run with this command rmiregistry -J-Djava.rmi.server.codebase=file:///<path-to-remote-classes>/Devil

© 2022 - 2024 — McMap. All rights reserved.