Create single JAR for all subproject test classes (Java)


I have a number of java subprojects under one root project, and I would like to gather all the compiled test classes in the subprojects and make one big JAR out of them.

The following discussion provides a good starting point but I can not seem to get it to work:

I tried doing something like this in the root project build.gradle:

task testJar(type: Jar, dependsOn: subprojects.tasks[‘testClasses’] ) {
baseName = “foo”
subprojects.each { subproject →
from files(subproject.tasks[“test”].testClassesDir)

I keep on getting errors related to not finding the testClasses or test tasks:

Could not get unknown property ‘testClasses’ for task set of type org.gradle.api.internal.tasks.DefaultTaskContainer.

I’m very new to Gradle so I’m not sure if it’s because syntax changes since then, or if there’s something different in my project.

Anyone that can point me in the right direction?

I found out it was because I was missing this line:

subprojects.each { subproject → evaluationDependsOn( subproject.path ) }

Is there anyone willing to explain why? It is because I can only access project tasks after the evaluation phase?
How does evaluationDependsOn( subproject.path ) affect evaluation order?

You are not restricted from accessing the project tasks during the configuration phase, but there is still an evaluation ordering dependency. Gradle is executing the code in your build script to create the model, but you can’t reference a value until it has been created. By default, Gradle evaluates from the root down to children, in order alphanumerically at each level. Therefore, the testClasses task does not exist in the subprojects until after the root project has been evaluated.

The line you reference forces the project evaluation to be postponed until after the evaluation of the project specified. If your case just needs the evaluation to depend on child projects, you can likely simplify this line to use evaluationDependsOnChildren() instead.

1 Like