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

Java 设置SecurityManager时如何以编程方式创建JShell,java,jshell,Java,Jshell,我想在之前设置安全管理器时以编程方式创建JShell。但是,这会导致访问控制异常。如果没有安全管理器设置,代码将正常工作。我认为Java平台模块默认拥有所有权限 我应该设置或配置什么来创建JShell,而不会因安全管理器导致任何异常 下面是我尝试的代码。我使用OpenJDK12.0.2 策略文件: grant codeBase "file:${user.dir}/-" { permission java.security.AllPermission; }; grant codeBase

我想在之前设置安全管理器时以编程方式创建JShell。但是,这会导致访问控制异常。如果没有安全管理器设置,代码将正常工作。我认为Java平台模块默认拥有所有权限

我应该设置或配置什么来创建JShell,而不会因安全管理器导致任何异常

下面是我尝试的代码。我使用OpenJDK12.0.2

策略文件:

grant codeBase "file:${user.dir}/-" {
    permission java.security.AllPermission;
};
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;
};
java模块:

module test {

    requires jdk.jshell;
    requires java.logging;
}
班级:

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);
    }
}
我还尝试:

    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;
        });
    }
publicstaticvoidmain(字符串[]args){
URI URI=HelloJShell.class.getResource(“/conf/security/java.policy”).tori();
Policy=Policy.getInstance(“JavaPolicy”,新的uri参数);
Policy.setPolicy(Policy);
System.setSecurityManager(新的SecurityManager());
AccessController.doPrivileged((PrivilegedAction)(->{
try(JShell js=JShell.create()){
System.out.println(js);
}
返回null;
});
}
我希望JShell将毫无例外地创建

它抛出以下异常:

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
线程“main”java.lang.IllegalStateException中的异常:启动JShell执行引擎抛出:拒绝访问(“java.util.logging.LoggingPermission”“control”) jdk.jshell/jdk.jshell.jshell.(jshell.java:139) 位于jdk.jshell/jdk.jshell.jshell$Builder.build(jshell.java:405) 位于jdk.jshell/jdk.jshell.jshell.create(jshell.java:420) 位于test/test.HelloJShell.main(HelloJShell.java:10) 原因:java.security.AccessControlException:拒绝访问(“java.util.logging.LoggingPermission”“control”) 位于java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:472) 位于java.base/java.security.AccessController.checkPermission(AccessController.java:1044) 位于java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:408) 在java.logging/java.util.logging.LogManager.checkPermission(LogManager.java:2432)中 位于java.logging/java.util.logging.Logger.checkPermission(Logger.java:622) 位于java.logging/java.util.logging.Logger.setLevel(Logger.java:2001) 位于jdk.jshell/jdk.jshell.execution.FailOverExecutionControlProvider.logger(FailOverExecutionControlProvider.java:138) 在jdk.jshell/jdk.jshell.execution.FailOverExecutionControlProvider.generate(FailOverExecutionControlProvider.java:109) 位于jdk.jshell/jdk.jshell.spi.ExecutionControl.generate(ExecutionControl.java:179) 位于jdk.jshell/jdk.jshell.spi.ExecutionControl.generate(ExecutionControl.java:296) 在jdk.jshell/jdk.jshell.jshell.(jshell.java:136) ... 3个以上
我找到了解决方案。必须在策略文件中配置以下权限:

grant codeBase "file:${user.dir}/-" {
    permission java.security.AllPermission;
};
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;
};
其定义如下:

如果您使用的是模块化运行时映像(请参阅jlink工具),则可以 向映像中的应用程序和库模块授予权限 通过将jrt URL指定为策略文件中的代码基值。看见 JEP220:模块化运行时映像,了解有关jrt URL的更多信息


我找到了解决办法。必须在策略文件中配置以下权限:

grant codeBase "file:${user.dir}/-" {
    permission java.security.AllPermission;
};
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;
};
其定义如下:

如果您使用的是模块化运行时映像(请参阅jlink工具),则可以 向映像中的应用程序和库模块授予权限 通过将jrt URL指定为策略文件中的代码基值。看见 JEP220:模块化运行时映像,了解有关jrt URL的更多信息