Show List

How to set up Gradle Source Sets

Source Set

Source set is a collection of java source files and resource files that are compiled and assembled together for the execution.

Java applications typically have "main" and "test" source sets. Source set "main" is used for creating the application and "test" is used for creating the unit tests for the applications.

Each source set has its own set of dependencies, dependency configurations, compilation class path and path location where compiled class files are placed.

For each source set Java plugin adds below dependency configurations:

  • sourceSetImplementation - Compile time dependencies for the given source set. Used by sourceSetCompileClasspath, sourceSetRuntimeClasspath.
  • sourceSetCompileOnly - Compile time only dependencies for the given source set, not used at runtime.
  • sourceSetCompileClasspath (extends sourceSetCompileOnly, sourceSetImplementation) - Compile classpath, used when compiling source. Used by compileSourceSetJava.
  • sourceSetAnnotationProcessor - Annotation processors used during compilation of this source set.
  • sourceSetRuntimeOnly - Runtime only dependencies for the given source set.
  • sourceSetRuntimeClasspath (extends sourceSetRuntimeOnly, sourceSetImplementation) - Runtime classpath contains elements of the implementation, as well as runtime only elements.
For "main" source set, source set name is excluded from the configuration. E.g. for "main" the configuration would be RuntimeOnly. For "test" source set the configuration would be testRuntimeOnly.

Creating Additional Source Set


Need for additional Source Set
Sometimes additional source sets may need to be created for the project. For examples when we have to perform the integration test, there are additional dependencies on the external applications. Gradle supports setting up such additional source sets. Separate source set helps to:
  • Keep the tests/sources separate from one another for easy maintenance.
  • Allows to set up different class path, dependencies etc.

Steps for setting up the source set
  • Create java classes, resource files and their corresponding folders.
  • Add required dependencies (Such as to compile, implementation, runtime)
  • Configure compilation and runtime class paths for the source set
  • Create the task to associate with the source test. For example if it is a source set for integration test, task would be created to run those integration test.

Here is the screenshot with new source set "itest" added for the integration test. It has the folders for the required java classes and resources for the integration test. We will not go into code in these files but rather how we set up "itest" source set for the integration tests.
We are creating separate gradle file "integrationTest.gradle" for this new source set to apply the configuration and dependencies that are required for the integration test. In the gradle file we have to provide location of the source code and resources. Class path for compiling and running the code, dependent jars, any task we want to add for invoking the integration test. Here is the sample:

integrationTest.gradle
sourceSets {
itest {
java {
//Add classes from the main source set to the compilation class path.
// These may be needed to compile integration test source code
compileClasspath += sourceSets.main.output

//Add classes from the main source set to the runtime class path
//These may be needed to run integration test
runtimeClasspath += sourceSets.main.output

//Provide source directory
srcDir file('src/itest/java')
}
//Provide resource directory
resources.srcDir file('src/itest/resources')
}

}

configurations {
//Extending ensures the declared dependencies of production code (in main source code)
// also become dependencies of the integration tests

//implementation: Classes available at compile time and runtime
// but hides the internal dependency of the module to its consumer
itestImplementation.extendsFrom implementation

//runtimeOnly: Classes available at run time only
itestRuntimeOnly.extendsFrom runtimeOnly
}

//Adding Junit dependency for the integration test
dependencies {
itestImplementation 'org.junit.jupiter:junit-jupiter:5.7.1'
}

//Custom gradle task to run the integration test
task itest(type: Test) {
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
}
description = "Run integration tests"
group = "verification"
testClassesDirs = sourceSets.itest.output.classesDirs
classpath = sourceSets.itest.runtimeClasspath
}
This file has been created under gradle folder:
We can now apply this build config to the main "build.gradle" file using below apply from command:
apply from: file('gradle/integrationTest.gradle')
After gradle reload is complete, we can see the new itest task added under available tasks:

Source Code:

https://github.com/it-code-lab/SourceSet-Demo

    Leave a Comment


  • captcha text