我想在设置安全管理器之前以编程方式创建JShell。但是,这导致访问控制异常。如果没有安全管理器设置,代码将正常工作。我认为Java平台模块默认具有所有权限。
在没有安全管理器引起的任何异常的情况下,我应该设置或配置什么来创建JShell?
下面是我尝试的代码。我使用的是OpenJDK 12.0.2。
策略文件:
grant codeBase "file:${user.dir}/-" {
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;
});
}
我希望将毫无例外地创建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
答案 0 :(得分:0)
我找到了解决方案。有必要在策略文件中配置以下权限:
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作为codeBase值。看到 JEP 220:模块化运行时图像,有关jrt URL的更多信息。