To build a Java project, you use the Java Plugin. This plugin adds some tasks to your project, along with some configuration properties, which will compile and test your Java source code, and bundle it into a JAR file. We have in-depth coverage with many examples about the Java plugin, dependency management and multi-project builds in later chapters. In this chapter we want to give you an initial idea of how to build a Java project.
Let's look at a simple example. To use the Java plugin, add the following to your build file:
Example 6.1. Java plugin
build.gradle
usePlugin 'java'
Note: The code for this example can be found at samples/java/quickstart
This is all you need to define a Java project. This will apply the Java plugin to your project, which adds a number of tasks to your project.
You can use gradle -t
to list the tasks of a project. This will let you see
the tasks that the Java plugin has added to your project.
Executing
gradle libs
will compile, test and jar your code. Gradle looks for your
production source code under src/main/java
and your test source code under
src/test/java
. In addition, any files under src/main/resources
will be included in the JAR file as resources, and any files under src/test/resources
will be included in the classpath used to run the tests. All output files will end up under the
build
directory, with the JAR file ending up in the build/libs
directory.
Usually, a Java project will have some dependencies on external JAR files. To reference these JAR files in the project, you need to tell Gradle where to find them. In Gradle, artifacts such as JAR files, are located in a repository. A repository can be used for fetching the dependencies of a project, or for publishing the artifacts of a project, or both. For this example, we will use the public Maven repository:
Let's add some dependencies. Here, we will declare that our production classes have a compile-time dependency on commons collections, and that our test classes have a compile-time dependency on junit:
Example 6.3. Adding dependencies
build.gradle
dependencies { compile group: 'commons-collections', name: 'commons-collections', version: '3.2' testCompile group: 'junit', name: 'junit', version: '4.+' }
You can find out more in Chapter 25, Dependency Management.
The Java plugin adds a number of properties to your project. These properties have default values which are usually sufficient to get started. It's easy to change these values if they don't suit. Let's look at this for our sample. Here we will specify the version number for our Java project, along with the Java version our source is written in. We also add some attributes to the JAR manifest.
Example 6.4. Customization of MANIFEST.MF
build.gradle
sourceCompatibility = 1.5 version = '1.0' manifest.mainAttributes( 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version )
You can use gradle -r
to list the properties of a project. This will allow
you to see the properties added by the Java plugin, and their default values.
The tasks which the Java plugin adds are regular tasks, exactly the same as if they were declared in
the build file. This means you can use any of the mechanisms shown in earlier chapters to customise
these tasks. For example, you can set the properties of a task, add behaviour to a task, change the
dependencies of a task, or replace a task entirely. In our sample, we will configure the
test
task, which is of type
Test
, to
add a system property when the tests are executed:
Example 6.5. Adding system property
build.gradle
test { options.systemProperties['property'] = 'value' }
Usually the JAR file needs to be published somewhere. To do this, you need to tell Gradle where to publish the JAR file. In Gradle, artifacts such as JAR files are published to repositories. In our sample, we will publish to a local directory. You can also publish to a remote location, or multiple location.
Example 6.6. Publishing the JAR file
build.gradle
uploadArchives { repositories { flatDir(dirs: file('repos')) } }
To publish the JAR file, run gradle uploadArchives
.
To import your project into Eclipse, simply run gradle eclipse
. More on eclipse
task can be found in Section 16.13, “Eclipse”.
Here's the complete build file for our sample:
Example 6.7. Java example - complete build file
build.gradle
usePlugin 'java' sourceCompatibility = 1.5 version = '1.0' manifest.mainAttributes( 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version ) repositories { mavenCentral() } dependencies { compile group: 'commons-collections', name: 'commons-collections', version: '3.2' testCompile group: 'junit', name: 'junit', version: '4.+' } test { options.systemProperties['property'] = 'value' } uploadArchives { repositories { flatDir(dirs: file('repos')) } }
Now let's look at a typical multi-project build. Below is the layout for the project:
Example 6.8. Multi-project build - hierarchical layout
Build layout
multiproject/ api/ services/ webservice/ shared/
Note: The code for this example can be found at samples/java/multiproject
Here we have three projects. Project api
produces a JAR file which is shipped to the
client to provide them a Java client for your XML webservice. Project webservice
is a
webapp which returns XML. Project shared
contains code used both by api
and webservice
.
To define a multi-project build, you need to create a settings file. The settings
file lives in the root directory of the source tree, and specifies which projects to include in the
build. It must be called settings.gradle
. For this example, we are using a simple
hierarchical layout. Here is the corresponding settings file:
Example 6.9. Multi-project build - settings.gradle file
settings.gradle
include "shared", "api", "services:webservice"
You can find out more about the settings file in Chapter 28, Multi-project Builds.
For most multi-project builds, there is some configuration which is common to all projects.
In our sample, we will define this common configuration in the root project, using a technique called
configuration injection. Here, the root project is like a container and the
subprojects
method iterates over the elements of this container - the projects in
this instance - and injects the specified configuration. This way we can easily define the manifest
content for all archives, and some common dependencies:
Example 6.10. Multi-project build - common configuration
build.gradle
subprojects { usePlugin 'java' usePlugin 'eclipse' repositories { mavenCentral() } dependencies { testCompile 'junit:junit:4.4' } group = 'org.gradle' version = '1.0' manifest.mainAttributes(provider: 'gradle') }
Notice that our sample applies the Java plugin to each subproject. This means the tasks and
configuration properties we have seen in the previous section are available in each subproject.
So, you can compile, test, and JAR all the projects by running gradle libs
from
the root project directory.
You can add dependencies between projects in the same build, so that, for example, the JAR file of one
project is used to compile another project. In the api
build file we will add a dependency
on the JAR produced by the shared
project. Due to this dependency, Gradle will
ensure that project shared
always gets built before project api
.
Example 6.11. Multi-project build - dependencies between projects
api/build.gradle
dependencies { compile project(':shared') }
In this chapter, you have seen how to do some of the things you commonly need to build a Java based project. This chapter is not exhaustive, and there are many other things you can do with Java projects in Gradle. These are dealt with in later chapters. Also, a lot of the behaviour you have seen in this chapter is configurable. For example, you can change where Gradle looks Java source files, or add extra tasks, or you can change what any task actually does. Again, you will see how this works in later chapters.
You can find out more about the Java plugin in Chapter 16, The Java Plugin, and you can find more sample
Java projects in the samples/java
directory in the Gradle distribution.