As far as I understand, the codebase for RMI which I set on the client, will be passed to the server. The server then uses this codebase to locate classes which aren't in the servers classpath.
As long as all required classes are available in the servers classpath, the remote method invocation works just fine. I've then tried to remove a required class from the servers classpath and instead specified the new location for the required class in the codebase property when starting the RMI client. Unfortunately this will give me a ClassNotFoundException: java.lang.ClassNotFoundException: client.Pi
Stack trace:
java.rmi.ServerException: RemoteException occurred in server thread; nested exce
ption is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested excep
tion is:
java.lang.ClassNotFoundException: client.Pi
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Sou
rce)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Sour
ce)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknow
n Source)
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unkn
own Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at com.sun.proxy.$Proxy0.executeTask(Unknown Source)
at client.ComputePi.main(ComputePi.java:26)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested ex
ception is:
java.lang.ClassNotFoundException: client.Pi
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Sou
rce)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Sour
ce)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: client.Pi
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.rmi.server.LoaderHandler$Loader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at sun.rmi.server.LoaderHandler.loadClassForName(Unknown Source)
at sun.rmi.server.LoaderHandler.loadClass(Unknown Source)
at sun.rmi.server.LoaderHandler.loadClass(Unknown Source)
at java.rmi.server.RMIClassLoader$2.loadClass(Unknown Source)
at java.rmi.server.RMIClassLoader.loadClass(Unknown Source)
at sun.rmi.server.MarshalInputStream.resolveClass(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at sun.rmi.server.UnicastRef.unmarshalValue(Unknown Source)
... 11 more
Starting the server:
C:\TEMP\RMI\RMIDemo\src>java
-cp C:\Users\samue_000\public_html\classes\compute.jar;C:\TEMP\RMI\RMIDemo\src
-Djava.security.policy=server.policy
-Djava.rmi.server.useCodebaseOnly=false
engine.ComputeEngine
>> ComputeEngine bound
Starting the client:
C:\TEMP\RMI\RMIDemo\src>java
-cp C:\Users\samue_000\public_html\classes\compute.jar;c:\Temp\RMI\RMIDemo\src;c:\temp
-Djava.security.policy=client.policy
-Djava.rmi.server.codebase=file:/C:/Users/samue_000/public_html/classes
client.ComputePi
Within the classpath of the client (c:\temp) lies the required client.Pi class which the client requires too. In order to tell the server where this class lies, I put a copy in a separate folder and specified this folder with the codebase property. The exactly location of that class is C:/Users/samue_000/public_html/classes/client/Pi.class. Its all running on the same physical machine (no vm's). So I do not see why the server doesn't get the codebase from the client and loads the required client.Pi class.
I've tried to minimize the posted information to the required part to not to overfill this post. If there is further information required to help me solve this problem please let me know. It is driving me crazy. I'm working on this issues for hours and days...
Edit: I have used the almost same code as described in this article from oracle. The only difference is that I create the rmi registry programmatically instead of starting the registry separate. So there shouldn't be anything wrong with the code itself. As long as the Pi class is in the classpath of the server it works just fine. But as soon as the Pi class only exists within the codebase and the classpath of the Client it won't work anymore.
Normally RMI codebase URLs are HTTP URLs, and they normally refer to a JAR file, not a directory.
-Djava.rmi.server.codebase=file:/C:/Users/samue_000/pubic_html/classes
That's a file:
URL, and it's only going to work on the same system it applies to. If the server is on a different host it won't make head or tail of that.
However as it is all on the same machine it should work. Can you post the remote interface?