Chapter 16. 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.

16.1. Tasks

The Java plugin adds the tasks shown in Table 16.1, “Java plugin - tasks” to a project. These tasks constitute a lifecycle for Java builds.

Table 16.1. Java plugin - tasks

Task name Depends on Type
clean - Clean
processResources - Copy
compile - Compile
processTestResources - Copy
compileTests compile Compile
test compile, compileTests, processResources, processTestResources Test
javadoc - Javadoc
jar compile, processResources, 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

16.2. Project layout

The Java plugin assumes the project layout shown in Table 16.2, “Java plugin - default project layout”. This is configurable using the convention properties listed in the next section.

Table 16.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

16.3. Dependency management

The Java plugin adds a number of dependency configurations to your project, as shown in Table 16.3, “Java plugin - dependency configurations”. It assigns those configurations to tasks such as compile and test. To learn more about configurations see Section 25.3.1, “Configurations” and Section 26.2, “Artifacts and configurations”

Table 16.3. Java plugin - dependency configurations

Name Extends Used by tasks Meaning
compile - compile Compile time dependencies
runtime compile - Runtime dependencies
testCompile compile compileTests Additional dependencies for compiling tests.
testRuntime runtime, testCompile test Additional dependencies for running tests only.
archives - uploadArchives Artifacts (e.g. jars) produced by this project.
default runtime, archives - Artifacts produced and dependencies required by this project.

16.4. Convention properties

The Java plugin adds the convention properties shown in Table 16.4, “Java plugin - directory properties” and Table 16.6, “Java plugin - other properties”. [15] 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 16.5, “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 16.4. 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 test/resources [ srcRoot/test/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 16.5. Java plugin - floating directory properties

Property Type Default Value
floatingSrcDirs List empty
floatingResourceDirs List empty
floatingTestSrcDirs List empty
floatingTestResourceDirs List empty

Table 16.6. 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

16.5. 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 16.7. 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 16.8. Java plugin - Javadoc properties

Task Property Convention Property
srcDirs srcDirs
classesDir classesDir
destinationDir [javadocDir]

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

16.7. Resources

Gradle uses the Copy task for resource handling. It has two instances, processResources and processTestResources.

Table 16.9. Java plugin - processResource properties

Task Instance Task Property Convention Property
processResources sourceDirs resourceDirs
processResources destinationDir classesDir
processTestResources sourceDirs testResourceDirs
processTestResources destinationDir testClassesDir

The processResources task offers include and exclude directives as well as filters. Have a look at Copy to learn about the details.

16.8. Compile

The Compile task has two instances, compile and compileTests.

Table 16.10. Java plugin - 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

Have a look at Compile to learn about the details. The compile task delegates to Ant's javac task to do the compile. You can set most of the properties of the Ant javac task.

16.9. Test

The test task executes the unit tests which have been compiled by the compileTests task.

Table 16.11. Java plugin - 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).

Since 0.6.1 we scan up the inheritance tree into jar files on the test classpath.

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.

16.10. 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 26, Artifact Management.

16.11. 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 16.1. Creation of ZIP archive

build.gradle

usePlugin 'java'
version = 1.0

task myZip(type: Zip) {
    fileSet(dir: 'somedir')
}

println myZip.archiveName

Output of gradle -q myZip

> gradle -q myZip
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 16.2. Configuration of archive task - custom archive name

build.gradle

usePlugin 'java'
version = 1.0

task myZip(type: Zip) {
    fileSet(dir: 'somedir')
    baseName = 'customName'
}

println myZip.archiveName

Output of gradle -q myZip

> gradle -q myZip
customName-1.0.zip

You can further customize the archive names:

Example 16.3. Configuration of archive task - appendix & classifier

build.gradle

usePlugin 'java'
archivesBaseName = 'gradle'
version = 1.0

task myZip(type: Zip) {
    appendix = 'wrapper'
    classifier = 'src'
    fileSet(dir: 'somedir')
}

println myZip.archiveName

Output of gradle -q myZip

> gradle -q myZip
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 26, Artifact Management

16.11.1. Archive tasks

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

Table 16.12. 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 16.13. File container 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.

16.11.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 . [16] 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.

16.11.1.2. Adding content

To add content to an archive you must add file container to an archive (see Table 16.13, “File container 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 16.4. Adding content to archive - include & exclude

build.gradle

task zipWithFileSet(type: Zip) {
    fileSet(dir: 'contentDir') {
        include('**/*.txt')
        exclude('**/*.gif')
    }
}

You can add arbitrary files to an archive:

Example 16.5. Adding content to archive - arbitrary files

build.gradle

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

Other examples:

Example 16.6. Adding content to archive - zipFileSet

build.gradle

task zipWithZipFileSet(type: Zip) {
    zipFileSet(dir: 'contentDir') {
        include('**/*.txt')
        exclude('**/*.gif')
        prefix = 'myprefix'
    }
}

Example 16.7. Creation of TAR archive

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.

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

16.11.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 for all the jar or a war archives in your project.

Example 16.8. Customization of MANIFEST.MF

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 16.9. Customization of MANIFEST.MF for a particular archive

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.

16.11.1.5. MetaInf

The convention object of the Java Plugin has a metaInf property pointing to a list of FileSet objects. With these 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)

16.12. Uploading

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

16.13. Eclipse

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

16.13.1. Eclipse classpath

EclipseClasspath has a default instance with the name eclipseCp. It generates a .classpath file.

Table 16.14. Java plugin - Eclipse properties

Task Property Convention Property
srcDirs srcDirs + resourcesDirs
testSrcDirs testSrcDirs + testResourcesDirs
outputDirectory classesDir
testOutputDirectory testClassesDir
classpathLibs the resolve result for testRuntime

16.13.2. Eclipse project

EclipseProject has a default instance with the name eclipseProject. It generates a .project file.

Table 16.15. Java plugin - 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.



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

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