Chapter 15. The Java Plugin

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.

15.1. Tasks

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

te
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
buildConfigurationName The tasks which produce the artifacts in configuration ConfigurationName. Task
uploadConfigurationName The tasks which uploads the artifacts in configuration ConfigurationName. Upload

15.2. Project Layout

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

15.3. Configurations

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”

15.4. Convention Properties

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 projectDir/src
srcDirNames srcDirs [main/java] [ srcRoot/main/java]
resourceDirNames resourceDirs [main/resources] [ srcRoot/main/resources]
testSrcDirNames testSrcDirs [test/java] [ srcRoot/test/java]
testResourceDirNames testResourceDirs main/resources [ srcRoot/main/resources]
classesDirName classesDir classes buildDir/classes
testClassesDirName testClassesDir test-classes buildDir/test-classes
testResultsDirName testResultsDir test-results buildDir/test-results
testReportDirName testReportDir tests reportsDir/test
libsDirName libsDir libs buildDir/libs
distsDirName distsDir dists buildDir/dists
docsDirName docsDir docs buildDir/docs
javadocDirName javadocDir javadoc buildDir/javadoc
reportsDirName reportsDir reports buildDir/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. sourceCompatibility
archivesBaseName String projectName
manifest GradleManifest empty
metaInf List empty

15.5. Init

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).

15.6. Javadoc

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]

15.7. Clean

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.

15.8. Resources

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.

15.9. Compile

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.

15.10. Test

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.

15.11. Jar

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.

15.12. Adding archives

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.archiveName

Example 15.2. Output of gradle -q init

> gradle -q init
zipProject-1.0.zip

This 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.archiveName

Example 15.4. Output of gradle -q init

> gradle -q init
customName-1.0.zip

You 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.archiveName

Example 15.6. Output of gradle -q init

> gradle -q init
gradle-wrapper-1.0-src.zip

Often you will want to publish an archive, so that it is usable from another project. This process is described in Chapter 22, Artifact Management

15.12.1. Archive Tasks

An archive task is a task which produces an archive at execution time. The following archives tasks are available:

Table 15.11. Archive Tasks

Type Accepted file container Extends
Zip fileSet, fileCollection, zipFileSet AbstractArchiveTask
Tar fileSet, fileCollection, zipFileSet, tarFileSet Zip
Jar fileSet, fileCollection, zipFileSet Zip
War fileSet, fileCollection, zipFileSet Jar

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.

15.12.1.1. Common Properties

The name of the generated archive is assembled from the task properties baseName, appendix, version, classifier and extension into baseName-appendix-version-classifier.extension . [17] The assembled name is accessible via the 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.

15.12.1.2. Adding Content

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:

Example 15.8.  build.gradle

task zipWithFiles(type: Zip) {
    files('path_to_file1', 'path_to_file2')
}

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.

15.12.1.3. Merging

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.

15.12.1.4. Manifest

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.

15.12.1.5. MetaInf

The convention object of the Java Plugin has a metaInf property pointing to a list of FileSet objects. With this file sets you can define which files should be in the META-INF directory of a JAR or a WAR archive.

metaInf << new FileSet(someDir)

15.13. Uploading

How to upload your archives is described in Chapter 22, Artifact Management.

15.14. Eclipse

Gradle comes with a number of tasks for generating eclipse files for your projects.

15.14.1. Eclipse Classpath

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

15.14.2. Eclipse Project

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.



[16] The buildDir property is a property of the project object. It defaults to build.

[17] If any of these properties is empty the trailing - is not added to the name.