Gradle Java Plugin - only add to -classpath if folder exists

Hi,

I have the following project structure

build.gradle
folder/
   subprojectA/
   subprojectB/
      src/test/java
   subprojectC/

where build.gradle is configured using subprojects like so:

subprojects {
   apply plugin: 'java-library'
   sourceSets {
      a {
         compileClasspath += test.runtimeClasspath
         runtimeClasspath += test.runtimeClasspath
      }
      b {
         compileClasspath += test.runtimeClasspath
         runtimeClasspath += test.runtimeClasspath
      }
   }
}

The problem is that by generically applying this configuration to every single subproject, the generated -classpath input to java compilation sometimes provides a classpath to a folder that does not exist (i.e. the java-compiler-args.txt shows that compileBJava provides classpaths to folders that do not exist) so errors like this come up:

incorrect classpath: subprojectA/build/classes/java/test
incorrect classpath: subprojectA/build/resources/test
incorrect classpath: subprojectA/build/classes/java/main
incorrect classpath: subprojectA/build/resources/main
incorrect classpath: subprojectA/build/classes/java/a
incorrect classpath: subprojectA/build/resources/a
incorrect classpath: subprojectB/build/classes/java/test
incorrect classpath: subprojectB/build/resources/test

This happens when a particular subproject does not actually have files in a declare sourceSet. Is there any way to only add to classpath to java compilation args if the folder exists or do I have to manually configure every compileClasspath and runtimeClasspath for every single subproject?

Let me know if my explanation is unclear and needs more information to understand.

This code is invoked in Gradle’s configuration phase which is before any compile tasks have run, and before any class files exist. You should check for the existence of source files (eg .java files) rather than class files/folders.

Eg:

subprojects {
   apply plugin: 'java-library'
   FileTree testSources = fileTree('src/test/java').matching {
      include '**/*.java' 
   } 
   if (!testSources.empty) {
      sourceSets {
         a {
            compileClasspath += test.runtimeClasspath
            runtimeClasspath += test.runtimeClasspath
         }
         b {
            compileClasspath += test.runtimeClasspath
            runtimeClasspath += test.runtimeClasspath
         }
      } 
   }
}

You might also need to add task dependencies

compileAJava.dependsOn 'compileTestJava' 
compileBJava.dependsOn 'compileTestJava'