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

时间:2015-09-15 11:34:04

标签: java junit gradle

我正在尝试使用安全管理器来阻止开发人员在单元测试中编写和读取文件。为此,我们考虑使用自定义安全管理器类。因此,我们创建了一个自定义安全管理器,并在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 个答案:

答案 0 :(得分:2)

你做了一件事...经过大量的挖掘后,我得到了以下内容在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标志运行也很有帮助:

  • e.g。 gradle test -i

答案 1 :(得分:0)

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

因此解决方案是您必须提供带有SecurityManager的安全策略文件,或者您必须提供SecurityManager的自定义实现。

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