RMI绑定失败,使用"没有安全管理器:RMI类加载器被禁用"

时间:2017-01-26 12:59:14

标签: java rmi securitymanager

我将远程对象绑定到RMI注册表时遇到问题。我将代码缩减为一个非常简单的示例,当我在计算机上测试它时(Windows 10)。但是,如果我在另一台计算机(Windows 7)上启动它,当"NK"被调用时,我会得到这个例外:

registry.bind(id, remoteObject);

我不需要SecurityManager,因为所有类文件都在jar中,我不想使用动态代码加载功能。

为什么它会尝试加载安全管理器,为什么即使我定义了安全管理器也无法找到它?可能是它在一台机器上工作而不是另一台机器上的原因是什么?我认为代码是可以的,它必须有一些配置问题,但我不确定究竟配置错误。

这是远程接口和远程对象实现,我在Eclipse中将其作为runnable Jar导出为java.lang.ClassNotFoundException: rmitest.IRemote (no security manager: RMI class loader disabled)

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$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

2 个答案:

答案 0 :(得分:1)

问题是其他一些Java进程运行似乎干扰了注册表绑定。我不知道这个流氓过程究竟做了什么,但杀死它解决了错误。不需要安全管理器,只需像往常一样运行jar工作。

答案 1 :(得分:1)

问题在于其他一些Java流程' 提供了自己的注册表,它无法访问您的CLASSPATH。你会发现,如果你有一个比catch的空createRegistry()块更好的东西。