简体   繁体   English

设置SecurityManager时如何以编程方式创建JShell

[英]How to create JShell programmatically when SecurityManager is set

I want to create JShell programmatically when the security manager is set before. 我想在以前设置安全管理器时以编程方式创建JShell。 However, this causes an access control exception. 但是,这会导致访问控制异常。 Without the security manager set the code works correctly. 如果没有安全管理器设置,代码将正常工作。 I thought that the Java platform modules have all permissions by default. 我认为Java平台模块默认具有所有权限。

What shall I set or configure to create JShell without any exception caused by the security manager? 我应设置或配置什么以创建JShell,而不会由安全管理器引起任何异常?

Below is the code that I tried. 以下是我尝试过的代码。 I use OpenJDK 12.0.2. 我使用的是OpenJDK 12.0.2。

The policy file: 策略文件:

grant codeBase "file:${user.dir}/-" {
    permission java.security.AllPermission;
};

The java module: Java模块:

module test {

    requires jdk.jshell;
    requires java.logging;
}

The class: 班级:

package test;

import jdk.jshell.JShell;

public class HelloJShell {

    public static void main(String[] args) {

        URI uri = HelloJShell.class.getResource("/conf/security/java.policy").toURI();
        Policy policy = Policy.getInstance("JavaPolicy", new URIParameter(uri));
        Policy.setPolicy(policy);

        // When the line below is commented the code works fine. 
        System.setSecurityManager(new SecurityManager());

        JShell js = JShell.create();
        System.out.println(js);
    }
}

I also tried: 我也尝试过:

    public static void main(String[] args) {

        URI uri = HelloJShell.class.getResource("/conf/security/java.policy").toURI();
        Policy policy = Policy.getInstance("JavaPolicy", new URIParameter(uri));
        Policy.setPolicy(policy);

        System.setSecurityManager(new SecurityManager());
        AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
            try (JShell js = JShell.create()) {
                System.out.println(js);
            }
            return null;
        });
    }

I expect that the JShell will be created without an exception. 我希望将毫无例外地创建JShell。

It throws this exception: 它引发以下异常:

Exception in thread "main" java.lang.IllegalStateException: Launching JShell execution engine threw: access denied ("java.util.logging.LoggingPermission" "control")
    at jdk.jshell/jdk.jshell.JShell.<init>(JShell.java:139)
    at jdk.jshell/jdk.jshell.JShell$Builder.build(JShell.java:405)
    at jdk.jshell/jdk.jshell.JShell.create(JShell.java:420)
    at test/test.HelloJShell.main(HelloJShell.java:10)
Caused by: java.security.AccessControlException: access denied ("java.util.logging.LoggingPermission" "control")
    at java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
    at java.base/java.security.AccessController.checkPermission(AccessController.java:1044)
    at java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:408)
    at java.logging/java.util.logging.LogManager.checkPermission(LogManager.java:2432)
    at java.logging/java.util.logging.Logger.checkPermission(Logger.java:622)
    at java.logging/java.util.logging.Logger.setLevel(Logger.java:2001)
    at jdk.jshell/jdk.jshell.execution.FailOverExecutionControlProvider.logger(FailOverExecutionControlProvider.java:138)
    at jdk.jshell/jdk.jshell.execution.FailOverExecutionControlProvider.generate(FailOverExecutionControlProvider.java:109)
    at jdk.jshell/jdk.jshell.spi.ExecutionControl.generate(ExecutionControl.java:179)
    at jdk.jshell/jdk.jshell.spi.ExecutionControl.generate(ExecutionControl.java:296)
    at jdk.jshell/jdk.jshell.JShell.<init>(JShell.java:136)
    ... 3 more

I found the solution. 我找到了解决方案。 It is necessary to configure the following permissions in the policy file: 必须在策略文件中配置以下权限:

grant codeBase "jrt:/jdk.jshell" {
    permission java.security.AllPermission;
};

grant codeBase "jrt:/jdk.jdi" {
    permission java.security.AllPermission;
};

grant codeBase "jrt:/jdk.compiler" {
    permission java.security.AllPermission;
};

It is defined here: https://docs.oracle.com/en/java/javase/12/security/permissions-jdk1.html#GUID-7450CEFD-8EDC-495E-A7A3-6C2561FA4999 它在这里定义: https : //docs.oracle.com/en/java/javase/12/security/permissions-jdk1.html#GUID-7450CEFD-8EDC-495E-A7A3-6C2561FA4999

If you are using a modular runtime image (see the jlink tool), you can grant permissions to the application and library modules in the image by specifying a jrt URL as the codeBase value in a policy file. 如果使用模块化运行时映像(请参阅jlink工具),则可以通过在策略文件中将jrt URL指定为codeBase值来授予映像中的应用程序和库模块的权限。 See JEP 220: Modular Run-Time Images for more information about jrt URLs. 有关jrt URL的更多信息,请参见JEP 220:模块化运行时图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM