在使用Gradle运行JUnit时设置自定义的安全管理器

4
我正在尝试使用安全管理器来防止开发人员在单元测试中编写和读取文件。为此,我们考虑使用自定义Security Manager类。因此,我们创建了一个自定义的安全管理器,并在checkRead和checkWrite方法中抛出异常。
当我使用Java编译器从Intellij运行测试时,它可以正常运行。作为示例,我使用了以下BeforeClass方法:
    @BeforeClass
    public static void printSecurityManager() throws Exception {

        System.setSecurityManager(new BuildSecurityManager());

    }

但是当我使用 gradle clean test 运行这个测试时,Gradle 测试就会一直卡住没有响应。

于是,我尝试在 build.gradle 中安装安全管理器,方式如下(只是为了看看能否在此处插入安全管理器):

test {
    logger.warn("running tests from gradle")

    SecurityManager manager = System.getSecurityManager();
    if (manager == null) {
        println("there is no security manager!");
    }

    jvmArgs "-Djava.security.manager=java.lang.SecurityManager"

但是当我尝试运行这个程序时,出现了以下错误:
:test
java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "getClassLoader")
    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.ClassLoader.checkClassLoaderPermission(ClassLoader.java:1525)
    at java.lang.ClassLoader.getParent(ClassLoader.java:1371)
    at jarjar.org.gradle.process.internal.launcher.GradleWorkerMain.run(GradleWorkerMain.java:66)
    at jarjar.org.gradle.process.internal.launcher.GradleWorkerMain.main(GradleWorkerMain.java:74)
:test FAILED

那么,有没有办法在Gradle单元测试中插入自定义的安全管理器呢?
2个回答

4

你可能已经发现了什么... 经过大量的挖掘,我在JUnit测试类中实现了以下功能:

public class SomeTest {
    private static final SecurityManager SM = System.getSecurityManager();

    @BeforeClass
    public static void startup() throws Exception {

        System.setSecurityManager(new SecurityManager() {
            @Override
            public void checkPermission(Permission perm) {
            }

            @Override
            public void checkPermission(Permission perm, Object context) {
            }

            @Override
            public void checkExit(int status) {
                String message = "System exit requested with error " + status;
                throw new SecurityException(message);
            }
        });
    }

    @AfterClass
    public static void shutdown(){
        System.setSecurityManager(SM);
    }

    @Test(expected=SecurityException.class)
    public void someTestThatSystemExits()
    {
        System.exit(1);
    }
}

背景链接:

运行时添加 -i 和 -d 参数也是有帮助的:

  • 例如:gradle test -i

0

我在我的同事的帮助下找到了第二个问题的原因。AccessControlException的原因是java.lang提供的默认SecurityManager不允许应用程序获取类加载器。在gradle安装安全管理器后,它仍然尝试获取类加载器,因此出现了错误。

因此,解决方案要么是您必须使用SecurityManager提供安全策略文件,要么是您必须提供SecurityManager的自定义实现。

我还没有找到挂起问题的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接