Java拒绝访问属性权限



不熟悉并行/分布式计算,并且在我试图编写的客户机-服务器程序中遇到问题。应该发生的事情是,服务器从客户端接收到一个整数,并返回到它之前的所有数字的和(例如,用户输入5,服务器计算1+2+3+4+5,服务器返回15)。我还在努力弄清楚,所以我已经在客户端硬编码了输入。

服务器端是这样的:

import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
import java.net.*;
import java.util.*;
public class Server {
public static void main(String[]args) {
    try{
        int port = 16790;
        String host = "localhost";
        CalculateSumServerImpl export = new CalculateSumServerImpl();
        LocateRegistry.createRegistry(port);
        String registryURL = "rmi://" + host + ":" + port + "/sum";
        Naming.rebind(registryURL, export);
        System.out.println("Server ready");
    } catch (Exception e) {
        e.printStackTrace();
    }
}   }

//to calculate the sum
import java.rmi.*;
import java.rmi.server.*;
public class CalculateSumServerImpl extends UnicastRemoteObject implements     CalServerInterface {
public int n; //value entered
public int sum; //sum
protected CalculateSumServerImpl() throws RemoteException {
    super();
}
@Override
public int calculateSum(int n) throws RemoteException {
    n = (n*(n+1))/2; //sum of 1 + 2 + 3 + .. + n
    sum = n;
    return sum;
} }
//interface
import java.rmi.Remote;
public interface CalServerInterface extends Remote {
 public int calculateSum(int n ) throws java.rmi.RemoteException;
}

客户端:

import java.rmi.*;
import java.util.PropertyPermission;
public class Client {
public static void main(String[]args) {
    System.setSecurityManager(new java.rmi.RMISecurityManager());
    System.setProperty("java.net.preferIPv4Stack" , "true");
    try {
        int port = 16790;
        String host = "localhost";
        String registryURL = "rmi://" + host + ":" + port + "/sum";
        Project4ServerInterface obj = (Project4ServerInterface)Naming.lookup(registryURL);
        System.out.println("Lookup completed.");
        int output = obj.calculateSum(3);
        System.out.println("Sum is: " + output);
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.setProperty("java.net.preferIPv4Stack","true");
} }

并且我也在客户端实现了接口。

我在客户端得到的错误是:

线程"main"中的异常java.security.AccessControlException: access denied ("java.util. net ")PropertyPermission" "java.net.preferIPv4Stack" "write")java.security.AccessControlContext.checkPermission (AccessControlContext.java: 472)java.security.AccessController.checkPermission (AccessController.java: 884)java.lang.SecurityManager.checkPermission (SecurityManager.java: 549)java.lang.System.setProperty (System.java: 792)project04client.Client.main (Client.java: 10)

,错误指向以下代码行:

System.setProperty("java.net.preferIPv4Stack" , "true");

有人有解决这个错误的经验吗?

谢谢!

问题是您已经为整个(客户机)应用程序设置了一个不允许您修改系统属性的安全管理器。

简单的修复方法是在设置RMI安全管理器之前设置需要设置的系统属性。

或者,您可以完全摆脱System.setSecurityManager(...)调用。只有当您希望客户端能够从RMI服务下载类时,您(可能)才需要它。


我尝试在安全管理器之前设置系统属性并获得AccessControlException,拒绝套接字权限。

这没有多大意义。只有在有安全管理人员的情况下,你才会得到AccessControlException。不应该有……除非这是applet代码或在web浏览器中启动的类似代码。此外,我不知道为什么设置属性的调用会被拒绝,说你没有套接字权限。

当我完全取出安全管理器时,我得到一个指向接口的UnmarshalException。

您还需要将要解组的对象的类/接口添加到客户端类路径中。


实际上,我只是注意到RMISecurityManager的javadoc说:

" RMISecurityManager执行与SecurityManager相同的策略。RMI应用程序应该使用SecurityManager类或其他适当的SecurityManager实现来代替这个类。"

最新更新