How do I include java files as test resources?


(Chris Nix) #1

I am writing a Java annotation processor. My tests perform a compilation step, with test resources that include Java files. These tests complete fine if I statically reference the Java resource files by their path and filenames. However, I was hoping to protect against name refactorings of those resources files by grabbing the file URL as follows:

ClassLoader.getSystemResource(JavaClassIWantToTest.class.getSimpleName())

My IDE (IntelliJ Idea) is fine with this, however…

The gradle ‘resources’ source set appears to exclude java files by default, as described at http://www.gradle.org/docs/current/userguide/java_plugin.html. Subsequently, my ‘compileTestJava’ task fails, unable to find the referenced files for compilation.

I’ve tried:

sourceSets {
    test {
        resources {
            include '**/*.java'
        }
    }
}

to no avail.

Indeed,

sourceSets {
    test {
        resources.each { File f -> println f }
    }
}

shows that the java files are included at this stage anyway, which might explain why my ‘include’ has no effect.

So how can I include java files as test resources for my annotation processor?


(Peter Niederwieser) #2

I don’t think Java files get filtered from resources. And doesn’t the problem occur when running the test, rather than when compiling it? Anyway, it’s probably a matter of figuring out the right code to load the resources. If you need a ‘File’, try something like this (not tested):

String resourceName = JavaClassIWantToTest.class.getName().replace(".", "/");
URL resource = getClass().getClassLoader().getResource(resourceName);
File file = new File(resource.toURI());

Since you are referring to the class from the code (‘JavaClassIWantToTest.class’), you need to have the class under ‘src/test/java’ (or your test sources directory of choice). As a consequence, it will already be on the (test runtime) class path, and you don’t also have to make it a (Gradle) resource.

If an ‘InputStream’ is sufficient, ‘getClass().getClassLoader().getResourceAsStream(resourceName)’ is preferable.


(Chris Nix) #3

Thanks for taking time to consider this.

The test fails to compile.

I tried your suggestion, but unfortunately I get the same error, indicating to me that the Java file in /src/test/java is not on the classpath for compilation.

error: cannot find symbol
 String resourceName = JavaClassIWantToTest.class.getName().replace(".", "/");
                       ^

If I statically code the String ‘resouceName’ as “com/example/package/name/JavaClassIWantToTest.java”, then the test works.


(Peter Niederwieser) #4

The sources to be compiled are never on their own compile class path, but of course they can still refer to each other. Perhaps you didn’t fully explain your setup.


(Chris Nix) #5

Thanks for taking time to consider this.

The test fails to compile.

I tried your suggestion, but unfortunately I get the same error, indicating to me that the Java file in /src/test/java is not on the classpath for compilation.

error: cannot find symbol
 String resourceName = JavaClassIWantToTest.class.getName().replace(".", "/");
                       ^

If I statically code the String ‘resouceName’ as “com/example/package/name/JavaClassIWantToTest.java”, then the test works.