昨天我试着开始使用Java RMI.我找到了这个sun教程(http://java.sun.com/docs/books/tutorial/rmi/index.html)并开始使用服务器实现.但每次我开始计划(rmiregistry正在运行)我得到一个带有以下StackTrace的AccessControlException:
LoginImpl exception: java.security.AccessControlException: access denied (java.io.FilePermission \\\C\ProjX\server\serverProj\bin\usermanager read) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:264) at java.security.AccessController.checkPermission(AccessController.java:427) at java.lang.SecurityManager.checkPermission(SecurityManager.java:532) at java.lang.SecurityManager.checkRead(SecurityManager.java:871) at java.io.File.exists(File.java:700) at sun.net.www.protocol.file.Handler.openConnection(Handler.java:80) at sun.net.www.protocol.file.Handler.openConnection(Handler.java:55) at java.net.URL.openConnection(URL.java:943) at sun.rmi.server.LoaderHandler.addPermissionsForURLs(LoaderHandler.java:1020) at sun.rmi.server.LoaderHandler.access$300(LoaderHandler.java:52) at sun.rmi.server.LoaderHandler$Loader.(LoaderHandler.java:1108) at sun.rmi.server.LoaderHandler$Loader. (LoaderHandler.java:1089) at sun.rmi.server.LoaderHandler$1.run(LoaderHandler.java:861) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.server.LoaderHandler.lookupLoader(LoaderHandler.java:858) at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:541) at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:628) at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:294) at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:238) at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1494) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1457) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1693) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1299) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:339) at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source) at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:375) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:240) at sun.rmi.transport.Transport$1.run(Transport.java:153) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:149) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701) at java.lang.Thread.run(Thread.java:595) at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source) at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source) at sun.rmi.server.UnicastRef.invoke(Unknown Source) at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source) at startserver.StartServer.main(StartServer.java:22)
我的server.policy文件如下所示:
grant { permission java.security.AllPermission; };
但我也试过这个......
grant { permission java.security.AllPermission; permission java.io.FilePermission "file://C:/ProjX/server/serverProj/bin/usermanager", "read"; };
......而这一个(以及其他几个:-():
grant codeBase "file:///-" { permission java.security.AllPermission; };
但在每种情况下结果都是一样的.是的,策略文件在路径中(当我将错误的语句写入策略文件时,我看到了Parse Exception).我尝试了其他几个"/"和"\"星座,但它没有效果.
我使用Eclipse,我的VM-Parameters是这样的:
-cp C:\ProjX\server\serverProj\bin\usermanager\ -Djava.rmi.server.codebase=file://C:/ProjX/server/serverProj/bin/usermanager/ -Djava.rmi.server.hostname=XYZ (anonymized) -Djava.security.policy=server.policy
编译的Remote-Interface和接口实现类(LoginImpl)类在此路径中:"C:/ ProjX/server/serverProj/bin/usermanager /".我将instub实例化并重新绑定到注册表的主要方法是在另一个包中,如下所示:
public static void main(String[] args) { if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); } try { String name = "Login"; Login login = new LoginImpl(); Login stub = (Login) UnicastRemoteObject.exportObject(login, 0); Registry registry = LocateRegistry.getRegistry(); registry.rebind(name, stub); System.out.println("LoginImpl bound"); } catch (Exception e) { System.err.println("LoginImpl exception:"); e.printStackTrace(); } }
有人对我有建议吗?谢谢你的帮助.
所以问题是一样的(java.rmi.UnmarshalException表明更改代码库不是我的AccessControlException的解决方案).不,我不想买插件"G B";-).
授予所有代码的所有权限非常糟糕.任何RMI客户端都可以按用户身份执行所需操作.通常尝试尽可能合理地限制权限,尤其是当您不知道代码的来源时.
回到问题......
-Djava.rmi.server.codebase=file://C:/ProjX/server/serverProj/bin/usermanager/
那应该是"file:///C:/..."
或者"file:/C:/..."
.想想http."http://C:/..."
指的是一个名为的主机C
.请注意,异常消息已删除冒号,因为这只是端口号的语法.
即使您授予所有代码权限,您获得安全异常的原因是RMI在给定URL的情况下将权限限制为适当的权限(使用AccessController doPrivileged两个参数形式).
好的,我有它.它不是rmiregistry属性(没有任何参数工作).我的代码库VM-Parameter中有两个错误:
-cp C:\ProjX\server\serverProj\bin\usermanager\ -Djava.rmi.server.codebase=file://C:/ProjX/server/serverProj/bin/usermanager/ -Djava.rmi.server.hostname=XYZ (anonymized) -Djava.security.policy=server.policy
......应该看起来像这样:
-Djava.rmi.server.codebase=file:/C:/ProjX/server/serverProj/bin/ -Djava.rmi.server.hostname=XYZ (anonymized) -Djava.security.policy=server.policy
=> file:/(只有一个斜杠)+错误的包结束.
但是我的第一个想法是,跟踪是如此令人困惑,政策文件或策略配置必定是错误的.
不过:谢谢你的帮助和快乐的黑客攻击.;-)