Gradle for Java - Basic Steps

Learning something new is always challenging. One of the difficulties I have, is to filter all the available information in order to reach a basic understanding. Heere are the steps I followed, in order to get started with Gradle for Java projects.

Setting up a Hello World project

Gradle provides the Build Init Plugin, which in turn provides tasks to bootstrap the process of creating a new Gradle build/project. The command gradle init --type java-application, will generate a Java project with the java and test directories in the conventional locations and some more files that are Gradle specific.

Filesystem-Tree

  • build.gradle is the file which builds the project. Most of the work will be done here.
  • settings.gradle is a file for custom operations in Gradle like multi-module projects
  • gradle directory contains the Gradle Wrapper which is simply a script that builds the project, without the need to download and install Gradle software in any machine. This is good for example, when you build the project in a Jenkins server.

The command gradle clean build will build the project and a jar file, with the main compiled classes, will be produced under the build folder. For an executable jar, the following lines should be added to the build.gradle:

jar {
    manifest {
        attributes 'Main-Class': 'App'
    }
}

Gradle Basic Concepts

The gradle.build is the file where a project’s build is described, using a Groovy based DSL. The build process is described using one or more task { } code blocks. Many common tasks have been gathered on what is called plugins, which are complementary to the Gradle Core. In the current build the java plugin is applied, so there is no need to create any custom task. The command gradle tasks --all will return a list of all the available tasks in a project. Any task can be invoked by simply running gradle task-name.

Properties

Every project in Gradle inherits some standard properties like name, description, etc. We will define values for some of them:

project.group=tutorials
project.decription=A PoC for Gradle

A project can also inherit properties from the applied plugins. From the Java plugin we have access to the bellow:

sourceCompatibility = 1.8
targetCompatibility = 1.8

Additionally to those properties, a project can maintain a map of extra properties, which can be added in the script like below:

ext {
    aDependencyVersion = "3.1.0.RELEASE"
    aRandomProperty = "rando@property.org"
}

Repository

The repositories {} code block is were the repository for the project is configured. Popular repositories are the mavenCentral(), jcenter(), google(). Custom repositories can be defined as well as shown below

repositories {
    jcenter()
    maven {
        url "https://company.artifactory/artifactory/libs"
    }
}

Dependency Management

The dependencies {} code block is were all extrernal dependencies of a project are declared. The Java plugin provides compile for compile time dependencies and testCompile for testing dependencies. Additionally to that, Gradle provides various annotations for declaring annotations, which we can see below:

dependencies {
  //For dependencies that will be downloaded from repositories
  //group:name:version syntax is used
  compile 'commons-lang:commons-lang:2.6'
  testCompile 'org.mockito:mockito:1.9.0-rc1'

  //map-style notation, for dependencies found in repositories.
  compile group: 'com.google.code.guice', name: 'guice', version: '1.0'

  //for including specific file in the classpath from the local file system.
  compile files('hibernate.jar', 'libs/spring.jar')

  //for including files under a local directory in the classpath.
  compile fileTree('libs')
}

Packaging

The jar task is the one that assembles a jar archive containing the compiled classes of the project. There is no build-in mechanism to generate a fat jar. We can do so, by defining our own task like below:

task fatJar(type:Jar) {
  manifest {
    attributes 'Main-Class': 'path.to.main.Class'
  }
  baseName = project.name + '-shaded'
  from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }}
}
with jar
}

or just use the Shadow Plugin, which will provide us with a shadowJar task.

Resources

For more detail information on Gradle and what can be done, visit the official Gradle user quide, as well as the standard plugins and the community plugins.