I have an issue binding a remote object to the RMI registry. I've reduced my code to a very simple example that works fine when I test it on my computer (Windows 10). But if I start it on another computer (Windows 7), when registry.bind(id, remoteObject);
gets called, I get this exception:
java.lang.ClassNotFoundException:
rmitest.IRemote (no security manager: RMI class loader disabled)
I shouldn't need a SecurityManager since all class files are in the jar and I don't want to use the dynamic code loading feature.
Why does it try to load a security manager and why can't it find one even if I define one? What could be the reason that it works on one machine but not another? I think the code is ok and it must some configuration issue, but I'm not sure what exactly is configured wrong.
Here is the remote interface and remote object implementation, which I exported as runnable Jar in Eclipse as rmitest.jar
.
public interface IRemote extends Remote {
void foo() throws RemoteException;
}
public class RemoteImpl extends UnicastRemoteObject implements IRemote {
private static Registry registry;
public RemoteImpl() throws RemoteException {
super();
}
public static void main(final String[] args) throws Exception {
try {
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
} catch (final Exception e) {
// already created
}
registry = LocateRegistry.getRegistry(Registry.REGISTRY_PORT);
registry.bind(UUID.randomUUID().toString(), new RemoteImpl());
System.out.println("Binding successful");
}
@Override
public void foo() throws RemoteException {
System.out.println("foo");
}
}
Here is the full stack trace, it throws in the line where registry.bind
gets called and is exactly the same when running with either of the following commands:
java -jar rmitest.jar
or
java -Djava.security.manager -Djava.security.policy=policy -jar rmitest.jar
It's quite strange that apparently in both cases a security manager is required but even in the second case it can't find one.
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: rmitest.IRemote (no security manager: RMI class loader disabled)
at sun.rmi.server.UnicastServerRef.oldDispatch(Unknown Source)
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 Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$256(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
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(StreamRemoteCall.java:276)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:253)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:379)
at sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source)
at rmitest.RemoteImpl.main(RemoteImpl.java:29)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: rmitest.IRemote (no security manager: RMI class loader disabled)
at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
at sun.rmi.server.UnicastServerRef.oldDispatch(Unknown Source)
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 Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$256(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
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: rmitest.IRemote (no security manager: RMI class loader disabled)
at sun.rmi.server.LoaderHandler.loadProxyClass(Unknown Source)
at java.rmi.server.RMIClassLoader$2.loadProxyClass(Unknown Source)
at java.rmi.server.RMIClassLoader.loadProxyClass(Unknown Source)
at sun.rmi.server.MarshalInputStream.resolveProxyClass(Unknown Source)
at java.io.ObjectInputStream.readProxyDesc(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)
... 15 more
Here is the policy file, which should allow everything:
grant {
permission java.security.AllPermission;
};
The problem was 'some other Java process' that was providing its own Registry, which didn't have access to your CLASSPATH. You would have found that if you had something better than an empty catch
block for createRegistry()
.