Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting a custom Security Manager when running JUnit with Gradle

Tags:

java

junit

gradle

I'm trying to use a security manager to refrain the developers from writing and reading files in Unit Tests. In order to do that, we think of using a custom Security Manager class. So we created a custom security manager and throw exceptions in checkRead and checkWrite methods.

So when I run the tests from Intellij using the java compiler it runs fine.

As an example I am using the following BeforeClass method:

    @BeforeClass
    public static void printSecurityManager() throws Exception {

        System.setSecurityManager(new BuildSecurityManager());

    }

But when I run this test using gradle clean test, the gradle test just hangs and does not respond.

Then, I tried to install the security manager using build.gradle in the following way(just to see if I can actually insert a security manager here):

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"

But when I tried to run this, I get the following error:

: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

So is there a way to insert a custom Security Manager to Gradle for unit tests?

like image 953
LostMohican Avatar asked Sep 06 '25 03:09

LostMohican


1 Answers

You were onto something ... after a lot of digging I got the following to work in a JUnit test class:

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);
    }
}

Background links:

  • https://discuss.gradle.org/t/gradle-build-process-hangs-when-system-setsecuritymanager-new-securitymanager-is-called/11670
  • https://issues.gradle.org/browse/GRADLE-2170
  • http://gradle.1045684.n5.nabble.com/Infinite-wait-running-tests-td5561210.html
  • https://discuss.gradle.org/t/java-lang-internalerror-could-not-create-securitymanager-jarjar-org-gradle-process-internal-child-bootstrapsecuritymanager/2478
  • https://issues.gradle.org/browse/GRADLE-2759
  • http://docs.oracle.com/javase/7/docs/api/java/lang/SecurityManager.html

It was also helpful to run with the -i and -d flags:

  • e.g. gradle test -i
like image 102
StylusEater Avatar answered Sep 09 '25 20:09

StylusEater