The Java Plugin adds Java compilation, testing and bundling capabilities to a project. It serves as the basis for most of the other Gradle plugins.
The Java plugin adds the tasks shown in Table 15.1, “Java Plugin - Tasks” to a project. These tasks constitute a lifecycle for Java builds.
Table 15.1. Java Plugin - Tasks
| Task name | Depends on | Type |
clean
|
- |
Clean
|
init
|
- |
Task
|
processResources
|
init
|
Copy
|
compile
|
processResources
|
Compile
|
processTestResources
|
compile
|
Copy
|
compileTests
|
processTestResources
|
Compile
|
test
|
compileTests
|
Test
|
javadoc
|
- |
Javadoc
|
jar
|
test
|
Jar
|
libs
|
All Jar and War tasks in the project.
|
Task
|
dists
|
libs and all Zip and Tar tasks in the project.
|
Task
|
build
|
The tasks which produce the artifacts in configuration ConfigurationName.
|
Task
|
upload
|
The tasks which uploads the artifacts in configuration ConfigurationName.
|
Upload
|
The Java plugin assumes the project layout shown in Table 15.2, “Java Plugin - Default Project Layout”. This is configurable using the convention properties listed in the next section.
Table 15.2. Java Plugin - Default Project Layout
| Directory | Meaning |
src/main/java
|
Application/Library Java source |
src/main/resources
|
Application/Library resources |
src/test/java
|
Test Java source |
src/test/resources
|
Test resources |
The Java plugin adds a number of configurations to your project, as shown in Section 21.3.9, “Java Plugin and Dependency Management”. To learn more about configurations see Section 21.3.1, “Configurations” and Section 22.2, “Artifacts and Configurations”
The Java plugin adds the convention properties shown in Table 15.3, “Java Plugin - Directory Properties” and
Table 15.5, “Java Plugin - Other Properties”.
[16]
Gradle's conventions contain a convention for the directory hierarchy as well as conventions for the element
names of the hierarchy. For example the srcDirs are relative to the
srcRoot. Therefore srcDirs is a read-only property. If you want to
change the name of the source dirs you need to do this via the srcDirNames property. But
the paths you specify here are relative to the srcRoot. This has the
advantage to make bulk changes easy. If you change srcRoot from src
to source, this automatically applies to all directory properties which are relative to
srcRoot. As this also introduces an inflexibility, we have additional floating dirs,
which are not bound to any hierarchy (see Table 15.4, “Java Plugin - Floating Directory Properties”). For example code
generation tool could make use of this, by adding a source dir which is located in the build folder.
Table 15.3. Java Plugin - Directory Properties
| Directory Name Property | Directory File Property | Default Name | Default File |
| srcRootName | srcRoot |
src
|
|
| srcDirNames | srcDirs |
[main/java]
|
[
]
|
| resourceDirNames | resourceDirs |
[main/resources]
|
[
]
|
| testSrcDirNames | testSrcDirs |
[test/java]
|
[
]
|
| testResourceDirNames | testResourceDirs |
main/resources
|
[
]
|
| classesDirName | classesDir |
classes
|
|
| testClassesDirName | testClassesDir |
test-classes
|
|
| testResultsDirName | testResultsDir |
test-results
|
|
| testReportDirName | testReportDir |
tests
|
|
| libsDirName | libsDir |
libs
|
|
| distsDirName | distsDir |
dists
|
|
| docsDirName | docsDir |
docs
|
|
| javadocDirName | javadocDir |
javadoc
|
|
| reportsDirName | reportsDir |
reports
|
|
Table 15.4. Java Plugin - Floating Directory Properties
| Property | Type | Default Value |
| floatingSrcDirs | List | empty |
| floatingResourceDirs | List | empty |
| floatingTestSrcDirs | List | empty |
| floatingTestResourceDirs | List | empty |
Table 15.5. Java Plugin - Other Properties
| Property | Type | Default Value |
| sourceCompatibility |
JavaVersion
. Can also set using a String or a Number, eg
'1.5' or 1.5.
|
1.5
|
| targetCompatibility |
JavaVersion
. Can also set using a String or Number, eg
'1.5' or 1.5.
|
|
| archivesBaseName | String |
|
| manifest |
GradleManifest
|
empty |
| metaInf | List | empty |
The
init
task has no default action attached to it. It is meant to be a hook. You can add actions to it or associates
your custom tasks with it. The Java Plugin executes this task before any other of its tasks get executed
(except
clean
and
javadoc
which does not depends on init).
The
javadoc
task has no default association with any other task. It has no prerequisites on the actions of other tasks,
as it operates on the source. We support the core javadoc options and the options of the standard doclet
described in the reference documentation
of the Javadoc executable.
For some of the Javadoc options we provide defaults these defaults are only used when they are not set explicitly. Except for the sourcepath and classpath option for these options you can in addition to setting your custom values also make it so that the defaults get appended to these paths with the (alwaysAppendDefaultSourcepath and alwaysAppendDefaultClasspath toggles).
Table 15.6. Javadoc Options
| Javadoc option | Default value | When is the default used |
| destination directory | [javadocDir] | When the destination directory is not set explicitly |
| sourcepath | The java or groovy source directories | When the sourcepath is empty or when you set the alwaysAppendDefaultSourcepath to true |
| classpath | The dependencies from the compile configuration + the classesDir | When the classpath is empty or when you set the alwaysAppendDefaultClasspath to true |
| windowTitle | project name + version | When the window title is not set explicitly |
| subPackages | All first level sub directories in the srcDirs | When the following options are all empty: packageNames, sourceNames and subPackages |
For a complete list of supported Javadoc options consult the API documentation of the following classes:
CoreJavadocOptions
and
StandardJavadocDocletOptions
.
Table 15.7. Java Convention Object - Javadoc Properties
| Task Property | Convention Property |
| srcDirs | srcDirs |
| classesDir | classesDir |
| destinationDir | [javadocDir] |
The
clean
task simply removes the directory denoted by its
dir
property. This property is mapped to the
buildDir
property of the project. In future releases there will be more control of what gets deleted. If you need
more control now, you can use the Ant delete task.
Gradle uses the
Copy
task for resource handling. It has two instances,
processResources
and processTestResources.
Table 15.8. Java Convention Object - Resource Properties
| Task Instance | Task Property | Convention Property |
| processResources | sourceDirs | resourceDirs |
| processResources | destinationDir | classesDir |
| processTestResources | sourceDirs | testResourceDirs |
| processTestResources | destinationDir | testClassesDir |
The
processResources
task offers includes and excludes directives as well as filters. Have a look at
Copy
to learn about the details.
The
Compile
task has two instances,
compile
and compileTests.
Table 15.9. Java Convention Object - Compile Properties
| Task Instance | Task Property | Convention Property |
| compile | srcDirs | srcDirs |
| compile | destinationDir | classesDir |
| compile | sourceCompatibility | sourceCompatibility |
| compile | targetCompatibility | targetCompatibility |
| compileTests | srcDirs | testSrcDirs |
| compileTests | destinationDir | testClassesDir |
| compileTests | sourceCompatibility | sourceCompatibility |
| compileTests | targetCompatibility | targetCompatibility |
The classpath of the compile task is derived from two sources. One is the
configuration
assigned to the task by the Java plugin. The other classpath source is the
unmanagedClasspath
property: a list of files denoting a jar or a directory. Usually you create your classpath via the
configuration. The
unmanagedClasspath
is used internally by Gradle. This classpath is not shared between projects in a multi-project build. Nor is
it part of a dependency descriptor if you choose to upload your library to a repository. See
Section 21.3.9, “Java Plugin and Dependency Management”
how the Java plugin maps the configurations to the tasks. See also the whole chapter Chapter 21, Dependency Management
on dependency management.
Have a look at
Compile
to learn about the details. The compile task delegates to Ants javac task to do the compile. You can set most
of the properties of Ants javac task.
The
test
task executes the unit tests which have been compiled by the
compileTests
task.
Table 15.10. Java Convention Object - Test Properties
| Task Property | Convention Property |
| testClassesDir | testClassesDir |
| testResultsDir | testResultsDir |
| unmanagedClasspath | [classesDir] |
Have a look at
Test
for its complete API. Right now the test results are always in XML-format. The task has a
stopAtFailuresOrErrors
property to control the behavior when tests are failing. Test
always
executes all tests. It stops the build afterwards if
stopAtFailuresOrErrors
is true and there are failing tests or tests that have thrown an uncaught exception.
Per default the tests are run in a forked JVM and the fork is done per test. You can modify this behavior by setting forking to false or set the forkmode to once.
The Test task detects which classes are test classes by inspecting the compiled test classes. By default it scans all .class files. You can set custom includes / excludes, only those classes will be scanned. Depending on the Test framework used (JUnit / TestNG) the test class detection uses different criteria.
When using JUnit, we scan for both JUnit 3 and 4 test classes. If any of the following criteria match the class is considered to be a JUnit test class. Extend TestCase or GroovyTestCase, Class annotated with RunWith or contain a method annotated with Test (inherited test methods are detected).
When using TestNG, we scan for methods annotated with Test (inherited test methods are detected).
In case you don't want to use the test class detection, you can disable it by setting scanForTestClasses to false.
This will make the test task only use the includes / excludes to find test classes.
If scanForTestClasses is disabled and no include or exclude patterns are specified, the
respective defaults are used. For include this is **/*Tests.class", "**/*Test.class
and the for exclude it is **/Abstract*.class.
Both JUnit and TestNG are supported through their Ant tasks.
The jar task creates a JAR file containing the class files and resources of the
project. The JAR file is declared as an artifact in the archives dependency
configuration. This means that the JAR is available in the classpath of a dependent project. If you upload
your project into a repository, this JAR is declared as part of the dependency descriptor. To learn
more about how to work with archives and artifact configurations see Chapter 22, Artifact Management.
If you come from Maven you can have only one library JAR per project. With Gradle you can have as many as you want. You can also add WAR, ZIP and TAR archives to your project. They are all added the same way, so let's look at how you add a ZIP file.
Example 15.1.
build.gradle
usePlugin 'java'
version = 1.0
task myZip(type: Zip) {
fileSet(dir: 'somedir')
}
println myZip.archiveNameThis adds a Zip archive task with the name myZip which produces ZIP file
zipProject-1.0.zip. It is important to distinguish between the name of the archive task
and the name of the archive generated by the archive task. The name of the generated archive file is by
default the name of the project with the project version appended. The default name for archives can be
changed with the archivesBaseName project property. The name of the archive can also be
changed at any time later on.
There are a number of properties which you can set on an archive task. You can, for example, change the name of the archive:
Example 15.3.
build.gradle
usePlugin 'java'
version = 1.0
task myZip(type: Zip) {
fileSet(dir: 'somedir')
baseName = 'customName'
}
println myZip.archiveNameYou can further customize the archive names:
Example 15.5.
build.gradle
usePlugin 'java'
archivesBaseName = 'gradle'
version = 1.0
task myZip(type: Zip) {
appendix = 'wrapper'
classifier = 'src'
fileSet(dir: 'somedir')
}
println myZip.archiveNameOften you will want to publish an archive, so that it is usable from another project. This process is described in Chapter 22, Artifact Management
An archive task is a task which produces an archive at execution time. The following archives tasks are available:
Table 15.11. Archive Tasks
The following file containers are available:
Table 15.12. Filecontainer for Archives
| Type | Meaning |
FileSet
|
A set of files defined by a common baseDir and include/exclude patterns. |
ZipFileSet
|
Extends FileSet with additional properties known from Ant's zipfileset task. |
TarFileSet
|
Extends ZipFileSet with additional properties known from Ant's tarfileset task. |
FileCollection
|
An arbitrary collection of files to include in the archive. In contrast to a
FileSet they don't need to have a common basedir. There are a number of ways
of creating a FileCollection. For example, the Configuration
objects of a project implement FileCollection. You can also obtain a
FileCollection using the Project.files() method.
|
AntDirective
|
An arbitrary Ant resource declaration. |
To learn about all the details have a look at the javadoc of the archive task class or the file container class itself.
The name of the generated archive is assembled from the task properties baseName,
appendix, version, classifier and
extension into
.
[17]
The assembled name is accessible via the baseName-appendix-version-classifier.extension
archiveName property. The
name property denotes the name of the task, not the generated archive. An archive
task has also a customName property. If this property is set, the
archiveName property returns its value instead of assembling a name out of the
properties mentioned above.
Archives have a destinationDir property to specify where the generated archive
should be placed. It has also an archivePath property, which returns a File object
with the absolute path of the generated archive.
To add content to an archive you must add file container to an archive (see Table 15.12, “Filecontainer for Archives”). You can add as many file containers as you like. They behave pretty much the same as the Ant resources with similar names.
Example 15.7.
build.gradle
task zipWithFileSet(type: Zip) {
fileSet(dir: 'contentDir') {
include('**/*.txt')
exclude('**/*.gif')
}
}You can add arbitrary files to an archive:
Other examples:
Example 15.9.
build.gradle
task zipWithZipFileSet(type: Zip) {
zipFileSet(dir: 'contentDir') {
include('**/*.txt')
exclude('**/*.gif')
prefix = 'myprefix'
}
}Example 15.10.
build.gradle
task tarWithFileSet(type: Tar) {
tarFileSet(dir: 'contentDir') {
include('**/*.txt')
exclude('**/*.gif')
uid = 'myuid'
}
}There is also the option to add an arbitrary Ant expression describing an Ant resource.
myZipTask.antDirective {
zipgroupfileset(dir: new File(rootDir, 'lib'))
}This is for rather exotic use cases. Usually you should be fine with the file container provided by Gradle.
If you want to merge the content of other archives into the archive to be generated Gradle offers you
two methods. One is merge:
myZipTask.merge('path1/otherArchive1.zip', 'path2/otherArchive.tar.gz')This merges the whole content of the archive passed to the merge method into the generated archive. If you need more control which content of the archive should be merged and to what path, you can pass a closure to the merge method:
myZipTask.merge('path1/otherArchive1.zip', 'path2/otherArchive.tar.gz') {
include('**/*.txt')
exclude('**/*.gif')
prefix = 'myprefix'
}Under the hood Gradle scans the extension of the archives to be merged. According to the extension, it
creates a
ZipFileSet
or TarFileSet. The closure is applied to this newly created file container. There
is another method for merging called mergeGroup.
myZipTask.mergeGroup('path_to_dir_with_archives') {
include('**/*.zip')
exclude('**/*.tar.gz')
}With this method you can assign a set of archives to be merged. Those archives have to be located
under the directory you pass as an argument. You can define filters what archives should be included.
They are always included fully and you can't specify a path. If you need this features, you must use the
merge method.
The convention object of the Java Plugin has a manifest
property pointing to an instance of
GradleManifest
.
With this GradleManifest object you can define the content of the
MANIFEST.MF file of all the jar or a war archives in your project.
Example 15.11.
build.gradle
manifest.mainAttributes("Implementation-Title": "Gradle", "Implementation-Version": version)You can also define sections of a manifest file.
If a particular archive needs unique entries in its manifest you have to create your own
GradleManifest instance for it.
Example 15.12.
build.gradle
manifest.mainAttributes("Implementation-Title": "Gradle", "Implementation-Version": version)
myZipTask.manifest = new GradleManifest(manifest.createManifest())
myZipTask.manifest.mainAttributes(mykey: "myvalue")Passing the common manifest object to the constructor of GradleManifest
add the common manifest values to the task specific manifest instance.
How to upload your archives is described in Chapter 22, Artifact Management.
Gradle comes with a number of tasks for generating eclipse files for your projects.
EclipseClasspath
has a default instance with the name eclipseCp. It generates a
.classpath file.
Table 15.13. Java Convention Object - Eclipse Properties
| Task Property | Convention Property |
| srcDirs | srcDirs + resourcesDirs |
| testSrcDirs | testSrcDirs + testResourcesDirs |
| outputDirectory | classesDir |
| testOutputDirectory | testClassesDir |
| classpathLibs | the resolve result for
testRuntime
|
EclipseProject
has a default instance with the name eclipseProject. It generates a
.project file.
Table 15.14. Java Convention Object - Eclipse Project Properties
| Task Property | Convention Property |
| name | project.name |
| projectType | ProjectType.JAVA |
The java plugin also provides a task called
eclipse
which generates both of the eclipse tasks mentioned above. If you are using the war plugin,
eclipse
also leads to the execution of the
eclipseWtp
task.