RMI 绑定失败 "java.lang.ClassNotFoundException: rmitest.IRemote"
RMI binding fails with "java.lang.ClassNotFoundException: rmitest.IRemote"
我在将远程对象绑定到 RMI 注册表时遇到问题。我已将我的代码缩减为一个非常简单的示例,当我在我的计算机上测试它时可以正常工作 (Windows 10)。但是如果我在另一台计算机上启动它 (Windows 7),当 registry.bind(id, remoteObject);
被调用时,我得到这个异常:
java.lang.ClassNotFoundException:
rmitest.IRemote (no security manager: RMI class loader disabled)
我不需要 SecurityManager,因为所有 class 文件都在 jar 中,而且我不想使用动态代码加载功能。
为什么它会尝试加载一个安全管理器,为什么即使我定义了一个它也找不到?它可以在一台机器上运行但不能在另一台机器上运行的原因是什么?我认为代码没问题,肯定是配置问题,但我不确定到底是哪里配置错了。
这里是远程接口和远程对象实现,我在 Eclipse 中将其作为可运行的 Jar 导出为 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");
}
}
这是完整的堆栈跟踪,它在调用 registry.bind
的行中抛出,并且在 运行 以下任一命令时完全相同:
java -jar rmitest.jar
或
java -Djava.security.manager -Djava.security.policy=policy -jar rmitest.jar
很奇怪,显然在这两种情况下都需要安全管理器,但即使在第二种情况下也找不到。
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.run(Unknown Source)
at sun.rmi.transport.Transport.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$run6(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.run(Unknown Source)
at sun.rmi.transport.Transport.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$run6(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.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
这是策略文件,应该允许所有内容:
grant {
permission java.security.AllPermission;
};
问题出在其他 Java 进程 运行 上,它似乎干扰了注册表绑定。我不知道这个流氓进程到底做了什么,但杀死它解决了错误。不需要安全管理器,只需 运行 jar 现在就可以像往常一样工作了。
问题是 'some other Java process' 提供了自己的注册表, 无法访问您的 CLASSPATH。你会发现如果你有比 createRegistry()
.
的空 catch
块更好的东西
我在将远程对象绑定到 RMI 注册表时遇到问题。我已将我的代码缩减为一个非常简单的示例,当我在我的计算机上测试它时可以正常工作 (Windows 10)。但是如果我在另一台计算机上启动它 (Windows 7),当 registry.bind(id, remoteObject);
被调用时,我得到这个异常:
java.lang.ClassNotFoundException:
rmitest.IRemote (no security manager: RMI class loader disabled)
我不需要 SecurityManager,因为所有 class 文件都在 jar 中,而且我不想使用动态代码加载功能。
为什么它会尝试加载一个安全管理器,为什么即使我定义了一个它也找不到?它可以在一台机器上运行但不能在另一台机器上运行的原因是什么?我认为代码没问题,肯定是配置问题,但我不确定到底是哪里配置错了。
这里是远程接口和远程对象实现,我在 Eclipse 中将其作为可运行的 Jar 导出为 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");
}
}
这是完整的堆栈跟踪,它在调用 registry.bind
的行中抛出,并且在 运行 以下任一命令时完全相同:
java -jar rmitest.jar
或
java -Djava.security.manager -Djava.security.policy=policy -jar rmitest.jar
很奇怪,显然在这两种情况下都需要安全管理器,但即使在第二种情况下也找不到。
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.run(Unknown Source)
at sun.rmi.transport.Transport.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$run6(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.run(Unknown Source)
at sun.rmi.transport.Transport.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$run6(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.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
这是策略文件,应该允许所有内容:
grant {
permission java.security.AllPermission;
};
问题出在其他 Java 进程 运行 上,它似乎干扰了注册表绑定。我不知道这个流氓进程到底做了什么,但杀死它解决了错误。不需要安全管理器,只需 运行 jar 现在就可以像往常一样工作了。
问题是 'some other Java process' 提供了自己的注册表, 无法访问您的 CLASSPATH。你会发现如果你有比 createRegistry()
.
catch
块更好的东西