May 25, 2021 Gradle
The Java plug-in adds Java compilation, testing, and bundling capabilities to a project. It is the foundation service for many other Gradle plug-ins.
To use the Java plug-in, add in the build script:
Use the Java plug-in
build.gradle
apply plugin: 'java'
The Java plug-in introduces the concept of a source set. A source set is just a set of source files that are compiled and executed together. T hese source files may include Java source code files and resource files. O ther plug-ins add the ability to include source code files for Groovy and Scala in the source set. A source set has an associated compilation class path and a runtime class path.
One use of source sets is to logically group source files to describe their purpose. For example, you might use a source set to define an integration test suite, or you might use a separate source set to define the API and implementation classes for your project.
The Java plug-in defines two standard source sets, main and test. T he main source set contains the source code for your product, which is compiled and assembled into a JAR file. The test source set contains the source code for your unit tests, which are compiled and executed using JUnit or TestNG.
The Java plug-in adds a lot of tasks to your project, as shown below.
Table 23.1. Java plug-ins - tasks
The name of the task | Depends on | Type | Describe |
compileJava
|
Produces all the tasks in the compilation class path.
This includes tasks
jar
|
JavaCompile | Use javac to compile the Java source file in the product. |
processResources
|
- | Copy | Copy the production resource file into the production class directory. |
classes
|
processResources
。
Some plug-ins add additional compilation tasks.
|
Task | Assemble the production class catalog. |
compileTestJava
|
compile
plus all the tasks that produce the path to the test compilation class.
|
JavaCompile | Use javac to compile the test source file for Java. |
processTestResources
|
- | Copy | Copy the resource files for the test into the test's class directory. |
testClasses
|
processTestResources
。
Some plug-ins add additional test compilation tasks.
|
Task | Assemble the class catalog for the test. |
jar
|
compile
|
Jar | Assemble the JAR file |
javadoc
|
compile
|
Javadoc | Use Javadoc to generate API documentation for the Java source code for production |
test
|
compileTest
plus all the tasks that produce the test runtime class path.
|
Test | Run unit tests with JUnit or TestNG. |
uploadArchives
|
Use
jar
.
|
Upload |
Use
archives
configuration to upload artifacts that include JAR files.
|
clean
|
- | Delete | Delete the build directory for the project. |
TaskName
|
- | Delete |
Delete the output file produced by the specified task.
For example,
jar
file created in the jar task,
test
result created by the test task.
|
For each source set you add to the project, the Java plug-in adds the following compilation tasks:
Table 23.2. Java plug-in- source set task
The name of the task | Depends on | Type | Describe |
SourceSet
Java
|
All tasks that produce the source set compilation class path. | JavaCompile | Use javac to compile java source files in a given source set. |
SourceSet
Resources
|
- | Copy | Copy the resource files for a given source set into the class directory. |
sourceSet
Classes
|
SourceSet
R
esources。
Some plug-ins also add additional compilation tasks to the source set.
|
Task | Assemble the class catalog for a given source set. |
The Java plug-in also adds a number of tasks that make up the life cycle of the project:
Table 23.3. Java plug-ins - lifecycle tasks
The name of the task | Depends on | Type | Describe |
assemble
|
All archived items in the project,
jar
tasks.
Some plug-ins also add additional archiving tasks to the project.
|
Task | Assemble all the category files in the project. |
check
|
All verification items in the project,
test
tasks.
Some plug-ins also add additional verification tasks to the project.
|
Task | Perform all verification tasks in the project. |
build
|
assemble
|
Task | Complete the build of the project. |
buildNeeded
|
build
task.
|
Task | Perform the complete build of the project itself and all other projects on which it depends. |
buildDependents
|
build
task.
|
Task | Perform the complete build of the project itself and all other projects that depend on it. |
ConfigurationName
|
Tasks that use configurationName to generate artifacts. | Task | Assemble the components of the specified configuration. The task is added by the Base plug-in and implemented implicitly by the Java plug-in. |
ConfigurationName
|
Use the task of configuring ConfigurationName to upload artifacts. | Upload | Assemble and upload the components for the specified configuration. The task is added by the Base plug-in and implemented implicitly by the Java plug-in. |
UploadConfigurationName uses the task of configuring ConfigurationName to upload artifacts. U pload assembles and uploads the components of the specified configuration. T he task is added by the Base plug-in and implemented implicitly by the Java plug-in. The following illustration shows the relationships between these tasks.
Figure 23.1. Java plug-ins - tasks
Java plug-in - task
The Java plug-in assumes the project layout as shown below. N one of these directories need to exist, or what's in them. The Java plug-in compiles whatever it finds and handles anything that is missing.
Table 23.4. Java plug-in - default project layout
Directory | Significance |
src/main/java
|
Java source code for the product |
src/main/resources
|
The resources of the product |
src/test/java
|
Java tests the source code |
src/test/resources
|
Test the resource |
sourceSet
/java
|
Java source code for a given source set |
sourceSet
/resources
|
The resource for the given source set |
You can configure the layout of your project by configuring the appropriate source set. T his will be discussed in more detail in the following sections. Here is a short example of how to change the main Java and resource source directories.
Customize the Java source code layout
build.gradle
sourceSets {
main {
java {
srcDir 'src/java'
}
resources {
srcDir 'src/resources'
}
}
}
The Java plug-in adds a number of dependency configurations to the project, as shown in the following image. It specifies these configurations for tasks such as compileJava and test.
Table 23.5. Java plug-ins - Dependent on configuration
Name | Inherited from | Which tasks are used | Significance |
compile | - | compileJava | Compile-time dependencies |
runtime | compile | - | Runtime dependency |
testCompile | compile | compileTestJava | Additional dependencies for compiling tests |
testRuntime | runtime, testCompile | test | Used only for other dependencies that run tests |
archives | - | uploadArchives | Components produced by this project (e.g. jar packages). |
default | runtime | - | The default project on this project depends on the configuration. Contains the artifacts and dependencies required for this project to run. |
Figure 23.2. Java plug-in - Dependent on configuration
Java plug-ins - Dependent on configuration
For each source set you add to your project, the Java plug-in adds the following dependency configurations:
Table 23.6. Java plug-ins - Source sets depend on configuration
Name | Inherited from | Which tasks are used | Significance |
sourceSet Compile | - | compile SourceSet Java | Compilation-time dependency for a given source set |
sourceSet Runtime | sourceSet Compile | - | Run-time dependency for a given source set |
The Java plug-in adds a number of general properties to the project, as shown in the following image. You can use these properties in a build script as if they were properties of a project object.
Table 23.7. Java Plug-in - Directory Properties
The name of the property | Type | The default | Describe |
reportsDirName
|
String
|
reports
|
The report is generated to the build directory relative to its directory name. |
reportsDir
|
File
(read-only)
|
reportsDirName
|
The report is generated into this directory. |
testResultsDirName
|
String
|
test-results
|
Compared to the directory name of the build directory, the .xml the test report is generated into this directory. |
testResultsDir
|
File
(read-only)
|
testResultsDirName
|
The test report.xml file is generated into this directory. |
testReportDirName
|
String
|
tests
|
The test report is generated into the build directory relative to its directory name. |
testReportDir
|
File
(read-only)
|
testReportDirName
|
The test report is generated into this directory. |
libsDirName
|
String
|
libs
|
The class library is generated into the build directory relative to its directory name. |
libsDir
|
File
(read-only)
|
libsDirName
|
The class library is generated into this directory. |
distsDirName
|
String
|
distributions
|
The published files are generated into the build directory relative to the directory name of the build directory. |
distsDir
|
File
(read-only)
|
distsDirName
|
The files to be published are generated into this directory. |
docsDirName
|
String
|
docs
|
The document is generated into the build directory relative to its directory name. |
docsDir
|
File
(read-only)
|
docsDirName
|
The directory to build the document. |
dependencyCacheDirName
|
String
|
dependency-cache
|
The directory is used to cache the dependent information of the source code relative to the directory name of the build directory. |
dependencyCacheDir
|
File
(read-only)
|
dependencyCacheDirName
|
The directory is used to cache dependent information for the source code. |
Table 23.8. Java plug-in - other properties
The name of the property | Type | The default | Describe |
sourceSets
|
SourceSetContainer (read-only) | Not empty | Contains the source set of the project. |
sourceCompatibility
|
JavaVersion.
You can use strings or numbers to set
1.5
|
The value used by the current JVM | Java version compatibility when compiling Java source code. |
targetCompatibility
|
JavaVersion.
You can use strings or numbers to set
1.5
|
sourceCompatibility
|
The Java version of the class to build. |
archivesBaseName
|
String
|
projectName
|
Bassename for components such as JAR or ZIP files |
manifest
|
Manifest | An empty list | A list of all JAR files to include. |
These properties are provided by javaPluginConvention, BasePluginConvention, and ReportingBasePluginConvention for these types of general objects.
You can use the sourceSets property to access the source set of the project. T his is the container for the source set of the project, and its type is SourceSetContainer. I n addition, there is a script block for sourceSets, which can be passed in to configure the source set container. Source set containers are used almost as much as other containers, such as tasks.
Access the source set
build.gradle
// Various ways to access the main source set
println sourceSets.main.output.classesDir
println sourceSets['main'].output.classesDir
sourceSets {
println main.output.classesDir
}
sourceSets {
main {
println output.classesDir
}
}
// Iterate over the source sets
sourceSets.all {
println name
}
To configure an existing source set, you only need to use one of the access methods above to set the properties of the source set. T hese properties are described below. Here's an example of configuring main's Java and resource directories:
Configure the source code directory for the source set
build.gradle
sourceSets {
main {
java {
srcDir 'src/java'
}
resources {
srcDir 'src/resources'
}
}
}
The following table lists some important source set properties. You can see more details in SourceSet's API documentation.
Table 23.9. Java plug-in - Source set property
The name of the property | Type | The default | Describe |
name
|
String
(read-only)
|
Not empty | The name of the source set used to determine a source set. |
output
|
SourceSetOutput (read-only) | Not empty | The output file of the source set, containing the classes and resources it compiles. |
output.classesDir
|
File
|
name
|
The directory of the class of the source set to build. |
output.resourcesDir
|
File
|
name
|
The directory of the resources for the source set to be generated. |
compileClasspath
|
FileCollection |
SourceSet
configuration.
|
This class path is used when compiling the source file for the source set. |
runtimeClasspath
|
FileCollection |
SourceSet
configuration.
|
This class path is used when executing the class of the source set. |
java
|
SourceDirectorySet (read-only) | Not empty |
The Java source file for the source set.
Contains only the files in the
.java
and excludes all other files.
|
java.srcDirs
|
Set<File>
|
name
/java]
|
The source directory contains all Java source files for this source set. |
resources
|
SourceDirectorySet (read-only) | Not empty |
The resource file for this source set. C
ontains only resource files, and excludes all files found in the
.java
files.
Other plug-ins, such as the Groovy plug-in, exclude other types of files from the collection.
|
resources.srcDirs
|
Set<File>
|
name
/resources]
|
The source directory contains the resource files for this source set. |
allJava
|
SourceDirectorySet (read-only) |
java
|
All files in
.java
set.
Some plug-ins, such as the Groovy plug-in, add additional Java source files from the collection.
|
allSource
|
SourceDirectorySet (read-only) |
resources
+ java
|
All source files for the source set. C ontains all resource files and Java source files. Some plug-ins, such as the Groovy plug-in, add additional source files from the collection. |
To define a new source set, you only need to reference it in the sourceSets block. Here's an example:
Define a source set
build.gradle
sourceSets {
intTest
}
When you define a new source set, the Java plug-in adds some dependency configurations to the source set, as shown in Table 23.6, Java Plug-in - Source Set Dependency Configuration. You can use these configurations to define the compilation and runtime dependencies of the source set.
Define the source set dependency
build.gradle
sourceSets {
intTest
}
dependencies {
intTestCompile 'junit:junit:4.11'
intTestRuntime 'org.ow2.asm:asm-all:4.0'
}
The Java plug-in also adds a number of tasks to assemble the classes of the source set, as shown in Table 23.2, "Java Plug-ins - Source Settings Tasks." For example, for a source set called intTest, you can run the gradle intTestClasses to compile the int test class.
Compile the source set
The output of the gradle intTestClasses
> gradle intTestClasses
:compileIntTestJava
:processIntTestResources
:intTestClasses
BUILD SUCCESSFUL
Total time: 1 secs
Add a JAR package that contains the class of the source set
Example 23.8. Assemble a JAR file for a source set
build.gradle
task intTestJar(type: Jar) {
from sourceSets.intTest.output
}
Build Javadoc for a source set:
Example 23.9. Build Javadoc for a source set:
build.gradle
task intTestJavadoc(type: Javadoc) {
source sourceSets.intTest.allJava
}
Add a test suite to run tests in a source set
Example 23.10. Run the tests in the source set
build.gradle
task intTest(type: Test) {
testClassesDir = sourceSets.intTest.output.classesDir
classpath = sourceSets.intTest.runtimeClasspath
}
The Javadoc task is an instance of Javadoc. I t supports the core javadoc parameter options, as well as the standard doclet parameter options described in the reference documentation for the Javadoc executable. For a complete list of supported Javadoc parameter options, refer to the API documentation for the following classes: CoreJavadocOptions and Standard Javadoc DocletOptions.
Table 23.10. Java plug-in - Javadoc property
The task property | Type | The default |
classpath
|
FileCollection |
sourceSets.main.output
+ sourceSets.main.compileClasspath
|
source
|
FileTree. |
sourceSets.main.allJava
|
destinationDir
|
File
|
docsDir
/javadoc
|
title
|
String
|
The name and version of the project |
The clean task is an instance of Delete. It simply deletes the directory represented by its dir property.
Table 23.11. Java plug-ins - Clean performance
The task property | Type | The default |
dir
|
File
|
buildDir
|
Java plug-ins use Copy tasks for resource processing. I t adds an instance to each source set in the project. You can find more information about the copy task in section 16.6, Copy Files.
Table 23.12. Java plug-in-ProcessResources property
The task property | Type | The default |
srcDirs
|
Object
.
|
sourceSet
.resources
|
destinationDir
|
16.1
章节,“查找文件”中所讲到的任何一种方式来设置。
|
sourceSet
.output.resourcesDir
|
The Java plug-in adds a JavaCompile instance to each source set in the project. Some of the most common configuration options are shown below.
Table 23.13. Java plug-in - Compile property
The task property | Type | The default |
classpath
|
FileCollection |
sourceSet
.compileClasspath
|
source
|
FileTree |
sourceSet
.java
|
destinationDir
|
File
.
|
sourceSet
.output.classesDir
|
The compile task delegates Ant's javac task. S etting options.useAnt to false bypasses the Ant task and activates Gradle's direct compiler integration. In a future version of Gradle, it will be the default setting.
By default, the Java compiler runs in the Gradle process. S etting options.fork to true will cause compilation to appear in a separate process. I n the Ant javac task, this means that a new process will be fork for each compile task, which will slow down compilation. I nstead, Gradle's direct compiler integration (see above) reuses as many of the same compiler processes as possible. In both cases, all fork options specified using options.forkOptions will be valued.
The test task is an instance of the Test. I t automatically detects and executes all unit tests in the test source set. W hen the test is complete, it also generates a report. B oth JUnit and TestNG are supported. Take a look at Test's full API.
The test is performed in a separate JVM, isolated from the main build process. The Test task API lets you control when to start.
There are a number of properties that control the start of the test process. This includes system properties, JVM parameters, and java executables used.
You can specify whether you want to run your tests in parallel. G radle provides execution of parallel tests by running multiple test processes at the same time. E ach test process performs a single test in turn, so you generally don't need to do any configuration of your tests to take advantage of this. T he MaxParallelForks property specifies the maximum number of test processes that can be run at a given time. Its default value is 1, that is, the test is not performed in parallel.
The test process sets the org.gradle.test.worker system property to a unique identifier that can be used for file names or other resource identifiers.
You can specify that the test process be restarted after a certain number of test classes have been executed. T his is a useful alternative to allowing your test process to have a large heap memory. T he forkEvery property specifies the maximum number of test classes to execute in the test process. The default is that there is no limit to the number of tests that can be performed in each test process.
The task has a ignoreFailures property that controls the behavior of the test if it fails. T est always performs every test it detects. I f ignoreFailures is false and the test does not pass, it stops building. The default value for IgnoreFailures is false.
The testLogging property can configure which test events need to be logged and what log levels are used. B y default, only one concise message is printed for each failed test. See TestLoggingContainer to see how to adjust your test log printing to your preferences.
The test task provides a Test.getDebug() property that can be set to start so that the JVM waits for a debugger to connect to its 5005 port before performing the test.
This can also be enabled at call time via the --debug-vm task option.
Starting with Gradle 1.10, you can include only the specified tests, depending on the name pattern of the test. F iltering is a different mechanism than the inclusion or exclusion of test classes. I t will be described in the next paragraph (-Dtest.single, test.include, and friends). T he latter is based on files, such as testing the physical location of the implementation class. F ile-level test selection does not support many interesting cases, can be done with test-level filtering. Some of these scenarios are ready for Gradle to handle now, while others will be implemented in the future:
The test filtering function has the following characteristics:
Filter the tests in the build script
build.gradle
test {
filter {
//include specific method in any of the tests
includeTestsMatching "*UiCheck"
//include all tests from package
includeTestsMatching "org.gradle.internal.*"
//include all integration tests
includeTestsMatching "*IntegTest"
}
}
For more details and examples, see TestFilter's documentation.
Some examples of using command-line options:
This mechanism has been replaced by the above-mentioned "test filtering". S etting up a system property for taskName.single s testNamePattern will only perform those tests that match testNamePattern. T his taskName can be a complete multi-project path, such as "sub1:sub2:test", or just a task name. T estNamePattern will be used to form an inclusion pattern .class "/testNamePattern". I f this pattern cannot find any tests, an exception is thrown. T his is to keep you from thinking that the test passed. I f more than one sub-project is tested, the pattern is applied to each sub-project. I f a test case cannot be found in a particular sub-project, an exception is thrown. I n this case, you can use the pattern of path marking so that it applies only to test tasks for specific sub-projects. O r you can specify the full qualified name of the task you want to perform. Y ou can also specify multiple modes. Example:
The Test task detects which classes are test classes by examining the compiled test classes. B y default, it scans .class files. Y ou can set up custom includes or excludes so that only these classes are scanned. Depending on the test framework (JUnit or TestNG) used, different standards are used for test class detection.
When using JUnit, we scan the test classes for JUnit 3 and 4. This class is considered a JUnit test class if any of the following conditions are met:
When using TestNG, we scan all methods with @Test with a note.
Note that abstract classes are not executed. Gradle also scans the inheritance tree in the jar file in the test class path.
If you don't want to use test class detection, you can disable it by setting scanForTestClasses to false. T his will cause the test task to use only includes / excludes to find the test class. I f scanForTestClasses is disabled and no include or exclude mode is specified, the respective default values are used. The default value for include is "/.class", / and for exclude its default value is "/Abstract.class".
JUnit and TestNG can complexly group test methods.
To group Junit test classes and methods, JUnit 4.8 introduces the concept of categories. The test task implements a specification that lets you include and exclude the JUnit categories you want.
JUnit category
build.gradle
test {
useJUnit {
includeCategories 'org.gradle.junit.CategoryA'
excludeCategories 'org.gradle.junit.CategoryB'
}
}
The TestNG framework has a very similar concept. I n TestNG you can specify different test groups. Test groups that should be included or exclude from test execution can be configured in the test task.
Group TestNG tests
build.gradle
test {
useTestNG {
excludeGroups 'integrationTests'
includeGroups 'unitTests'
}
}
The test task produces the following results by default.
You can use the Test.setTestReport() method to disable HTML test reporting. Other results cannot be disabled at this time.
There is also a separate TestReport task type that generates HTML test reports from binary results generated by one or more Test task instances. T o use this task type, you need to define a destinationDir and the test results to include in the report. Here is an example of generating a joint report from unit tests for sub-projects:
Create a unit test report for multiple sub-projects
build.gradle
subprojects {
apply plugin: 'java'
// Disable the test report for the individual test task
test {
reports.html.enabled = false
}
}
task testReport(type: TestReport) {
destinationDir = file("$buildDir/reports/allTests")
// Include the results from the `test` task in all subprojects
reportOn subprojects*.test
}
You should note that the TestReport type combines the results of multiple test tasks and needs to aggregate the results of each test class. This means that if a given test class is executed by more than one test task, the test report will include all the execution results of that class, but it is difficult to distinguish between each execution of that class and their output.
TestNG supports paramethy test methods that allow a particular test method to execute multiple times with different inputs. Gradle includes its parameter values in the execution report of this method.
Given a paramethetic test method with two parameters called aParameterizedTestMethod, it will report using the name: aParameterizedTestMethod (to StringValueOfParam1, toStringValueOfParam2). This makes it easy to determine parameter values during a particular iterative process.
Table 23.14. Java plug-in - test property
The task property | Type | The default |
testClassesDir
|
File
|
sourceSets.test.output.classesDir
|
classpath
|
FileCollection |
sourceSets.test.runtimeClasspath
|
testResultsDir
|
File
|
testResultsDir
|
testReportDir
|
File
|
testReportDir
|
testSrcDirs
|
List<File>
|
sourceSets.test.java.srcDirs
|
The Jar task creates a JAR file that contains class files and project resources. T he JAR file is declared as a artifact in the archives dependency configuration. T his means that the JAR file is contained in a class path for an item that depends on it. I f you upload your project to the repository, the JAR file is declared as part of the dependency descriptor. You can learn how to use archives and configure artifacts in Section 16.8, "Create Archives" and Chapter 51.
Each jar or war object has a separate Manifest instance of the manifest property. W hen the archive is generated, the corresponding MANIFEST. The MF file is also written in.
Custom MANIFEST. Mf
build.gradle
jar {
manifest {
attributes("Implementation-Title": "Gradle", "Implementation-Version": version)
}
}
You can create a separate Manifest instance. It can be used to share manifest information for two jar packages.
Create a manifest object.
build.gradle
ext.sharedManifest = manifest {
attributes("Implementation-Title": "Gradle", "Implementation-Version": version)
}
task fooJar(type: Jar) {
manifest = project.manifest {
from sharedManifest
}
}
You can merge the other manifests into any of the Manifest objects. Other manifests may use file paths to describe, as in the example above, references to another Manifest object.
Specify a separate MANIFEST for archive. Mf
build.gradle
task barJar(type: Jar) {
manifest {
attributes key1: 'value1'
from sharedManifest, 'src/config/basemanifest.txt'
from('src/config/javabasemanifest.txt', 'src/config/libbasemanifest.txt') {
eachEntry { details ->
if (details.baseValue != details.mergeValue) {
details.value = baseValue
}
if (details.key == 'foo') {
details.exclude()
}
}
}
}
}
Manifest merges according to the order declared in the from statement. I f both the basic manifest and the manifest to merge define the value of the same key, the value of the manifest to merge is used by default. Y ou can completely customize the merge behavior by adding eachEntry action, which gives you access to one of its ManifestMergeDetails instances for each generated manifest. T his merge operation is not triggered immediately in the from statement. It's lazy, whether it's for generating a jar package, or calling writeTo or effectiveManifest
You can easily write a manifest to disk.
Specify a separate MANIFEST for archive. Mf
build.gradle
jar.manifest.writeTo("$buildDir/mymanifest.mf")