Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在启用java安全管理器时获取系统属性“os.arch”时,权限被拒绝_Java_Java.util.concurrent_Completable Future_Java Security_Java Security Manager - Fatal编程技术网

在启用java安全管理器时获取系统属性“os.arch”时,权限被拒绝

在启用java安全管理器时获取系统属性“os.arch”时,权限被拒绝,java,java.util.concurrent,completable-future,java-security,java-security-manager,Java,Java.util.concurrent,Completable Future,Java Security,Java Security Manager,我有一个简单的java应用程序ClientApp,它启用了java安全管理器。 此应用程序正在尝试调用获取os.arch系统属性的测试jar方法。由于这很耗时,我们正在使用Completable任务调用一个新线程 这是个例外 java.util.concurrent.ExecutionException: java.security.AccessControlException: access denied ("java.util.PropertyPermission" "os.arch" "r

我有一个简单的java应用程序ClientApp,它启用了java安全管理器。 此应用程序正在尝试调用获取os.arch系统属性的测试jar方法。由于这很耗时,我们正在使用Completable任务调用一个新线程

这是个例外

java.util.concurrent.ExecutionException: java.security.AccessControlException: access denied ("java.util.PropertyPermission" "os.arch" "read")
    at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
    at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
    at SecurityApplication.ClientApp.main(ClientApp.java:23)
Caused by: java.security.AccessControlException: access denied ("java.util.PropertyPermission" "os.arch" "read")
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
    at java.security.AccessController.checkPermission(AccessController.java:884)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1294)
    at java.lang.System.getProperty(System.java:717)
    at com.ravindra.CustomSupplier.get(CustomSupplier.java:10)
    at com.ravindra.CustomSupplier.get(CustomSupplier.java:5)
    at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590)
    at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1582)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
客户页:

import com.test.App;

public class ClientApp
{
    public static void main(String[] args)
    {
        //Enable security 
        SecurityManager securityManager = new SecurityManager();
        System.setSecurityManager(securityManager);

        TestApp app = new TestApp();

        Future<String> future = app.getOsArchitecture();

        try
        {
            // blocking Aysnc get Future call for result
            System.out.println(future.get());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
Test.jar有以下2个类文件

Test.java

final public class TestApp
{
    public Future<String> getOsArchitecture()
    {
        CompletableFuture<String> completableFuture
                = CompletableFuture.supplyAsync(new CustomSupplier());

        return completableFuture;
    }
}
CustomSupplier.java

public class CustomSupplier implements Supplier<String> {
    public CustomSupplier() {
    }

    public String get() {
        //Time consuming complex Task and finally return "os.arch"
        //...
        //...
        //...
        return System.getProperty("os.arch");
    }
}
但是,当我们禁用Java安全管理器时,程序会正确运行

非常感谢您的帮助。

默认的ForkJoinPool使用配置为没有权限的线程

一种解决方案是使用自定义线程工厂或使用普通线程的任何其他执行器实现创建新的ForkJoinPool实例。问题是,创建自己的线程池需要安全管理器授予相关权限

另一种方法是将查询作为特权操作执行,忽略调用线程的限制:

public class CustomSupplier implements Supplier<String> {
    public CustomSupplier() {
    }

    public String get() {
        //Time consuming complex Task and finally return "os.arch"
        //...
        //...
        //...
        return AccessController.doPrivileged(
            (PrivilegedAction<String>)() -> System.getProperty("os.arch"));
    }
}

System.getPropertyString具有单个哈希查找。那绝对不费时。即使是,异步执行操作但在提交后立即等待结果,只增加了一点所需的时间。耗时任务意味着与我的项目相关的业务逻辑,因此您正在执行一个耗时的异步任务,它不依赖于System.getPropertyos.arch的值,最后返回System.getPropertyos.arch的值,这与异步任务所做的工作无关?是的,您的回答是正确的。您好,我们已经解决了这个问题。API是以这样一种方式编写的,我们需要传递我们自己的Executor服务,这样它就不会使用ForkJoin公共池来创建线程。当我们创建自己的Executor服务时,它使用了应用程序上下文,因此它有权获取系统属性。我会尝试让您知道。谢谢
public class CustomSupplier implements Supplier<String> {
    public CustomSupplier() {
    }

    public String get() {
        //Time consuming complex Task and finally return "os.arch"
        //...
        //...
        //...
        return ARCH;
    }
    static final String ARCH = System.getProperty("os.arch");
}