A simple java project with Gradle

Jafar Karuthedath
7 min readNov 11, 2020

--

How do you create a Java project ? . Most probably you will be using IDE like Eclipse or IntelliJ. When I started Java programming, I started with Eclipse IDE to create a Java application where I could run it from the IDE and export as runnable jar. But later I have more requirements..

  • I wanted to use external libraries (sl4j, JSON etc.)
  • Create the application with a version and a given name
  • Build the application without any IDE
  • Execute the test cases
  • Publish the output jar into a repository
  • … and more

So how could I fulfill all this requirements ?. Using Gradle .

IDE like IntelliJ or Eclipse already have built in plugin to create Gradle projects. My goal here is to show you how to do without an IDE. Later you can import the project into any IDE and easily change the build script based on your requirements. To do this, we need some basic understanding about Gradle. Lets have some basic info for our quick start..

What is Gradle ?

Gradle is an open-source build automation tool that is designed to be flexible enough to build almost any type of software. That's nice to read, but how do I start with this tool ?.. How can I use it ?. Before we directly jumping into the Gradle configuration for Java, lets start something very simple. Lets create a gradle task to print “Hello World” to the console.

Gradle Installation

U:\>gradle -vWelcome to Gradle 6.7!
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

Note : If the version info is not displayed, please check if you have set the PATH properly, as mentioned in the official gradle page

Hello World with Gradle

How do we start writing code for gradle ?. Gradle provides a domain specific language, or DSL, for describing builds. This build language is available in Groovy and Kotlin.

Now lets start with our “Hello World”

  • Create a new directory “gradle-demo”
  • Create a file “build.gradle” in a directory
  • Write the following code
//Print a message to the console
task printHello() {
println “Hello World”
}
  • Open the terminal and execute gradle printHello
$ gradle -q printHello
> Configure project :
Hello World

build.gradle : The gradle command looks for a file called build.gradle in the current directory. The build script defines a project and its tasks.

Lets create some meaningful task with gradle. Create a task to copy all images from a directory.

Copy files

task copyImages(type: Copy) {
println “Copying images…”
from “${System.getProperty(‘user.dir’)}/data”
include “*.jpg”
into “${System.getProperty(‘user.dir’)}/images”
}

We copy all the files with the extension “jpg” by creating an instance of Gradle’s builtin Copy task and configuring it with the location of the input and output directory. System.getProperty(‘user.dir’) gets the current working directory.

Here is the official documentation more on gradle task .I would recommend to go through this to have a good understanding. https://docs.gradle.org/current/userguide/tutorial_using_tasks.html

Gradle plugin

As you know some idea how gradle task works, we can create task to fulfill all our requirements. But there is an easy way to achieve this by using gradle plugin concept. Plugin is set of tasks, such as compiling tasks, setting up source files etc. Applying a plugin to a project means that allows the plugin to extend the project’s capabilities.

For example, to configure a java project, we can use the plugin “java”.

plugins {
id 'java'
}

You can find a list of core plugins from gradle here : https://docs.gradle.org/current/userguide/plugin_reference.html

Gradle wrapper

The recommended way to execute any Gradle build is with the help of the Gradle Wrapper (in short just “Wrapper”). The Wrapper is a script that invokes a declared version of Gradle, downloading it beforehand if necessary. As a result, developers can get up and running with a Gradle project quickly without having to follow manual installation processes saving your company time and money.

Java project
Enough theories. Lets finally create our java project. Gradle provides a quick start by using gradle init command. This command creates the following things for us

  • Gradle wrapper
  • build.gradle with the required plugins and dependencies
  • Java application directory structure
  • A sample class with main method which prints HelloWorld
  • JUnit test classes.

Lets execute the command.

  • Create a folder and open a terminal
  • Execute gradle init --type java-application
gradle init --type java-application
Configuration on demand is an incubating feature.
Select build script DSL:
1: Groovy
2: Kotlin
Enter selection (default: Groovy) [1..2] 1
Select test framework:
1: JUnit 4
2: TestNG
3: Spock
4: JUnit Jupiter
Enter selection (default: JUnit 4) [1..4] 1
Project name (default: gradle-init):
Source package (default: gradle.init): com.example.gradle
> Task :init
Get more help with your project: https://docs.gradle.org/6.7/samples/sample_building_java_applications.html
BUILD SUCCESSFUL in 15s
2 actionable tasks: 2 executed

We get a project structure as follows

java project structure

You can open the project in any of your favorite IDE. For example I have imported the project into Eclipse as a gradle project

Execute the following gradle commands to see if all works

  • Open a command terminal on the project folder
  • Execute gradle build
  • Execute gradle run

Lets have a deeper look into the build.gradle

Application plugin

plugins {
id 'application'
}

The Application plugin facilitates creating an executable JVM application. It makes it easy to start the application locally during development, and to package the application as a TAR and/or ZIP including operating system specific start scripts.

To see the list of task being executed by the ‘application’ plugin, you can execute

gradle tasks --all

Repositories

repositories {
jcenter()
}

A repository is storage location for software packages (E.g. library jars). Gradle can resolve dependencies from one or many repositories based on Maven, Ivy or flat directory formats. By specifying jcenter as the repository, gradle knows where to look all the dependency jars. Other popular repository is mavenCentral

A detailed description of repositories can be read here :

Dependencies

dependencies {
testImplementation 'junit:junit:4.13'
implementation 'com.google.guava:guava:29.0-jre'
}

Every dependency declared for a Gradle project applies to a specific scope. For example testImplementation should be used for compiling source code whereas implementation need to be available also at runtime.

Example : To add the JSON dependency to the project,

dependencies {
compile group: 'org.json', name: 'json', version: '20200518'
}
  • Add the desired code in the App.java
public JSONObject createJSONObject(String data) {
return new JSONObject(data);
}
  • Execute gradle build

More details on gradle dependencies can be read here :

Ok.. now you should be familiar with the basics of gradle and how to use a plugin to build your project. Lets create a gradle task to build a runnable jar.

Runnable Jar

The runnable jar contains a MANIFEST.MF file, which defines the Main class to be executed when the jar is run. I name the task as fatJar because we are creating a jar, copying all the dependencies to the jar. The build script below, may be confusing to you, but that is the Groovy syntax. We create a manifest file with the main class name and copying all the dependencies to the jar.

task fatJar(type: Jar) { manifest {attributes 'Main-Class': 'com.example.gradle.App'}
from {
configurations.compile.collect
{ it.isDirectory() ? it : zipTree(it) }
}with jar
}
  • Execute gradle fatJar
gradle --info fatJar
  • Run the application
java -jar app\build\libs\app.jarHello World!
{"key1":"value1","key2":"value2"}

We can also create a runnable jar with all its dependencies copied and adding the classpath to the manifest. To do that, lets create a task to copy all the dependency jars into a folder

def dependsDir = "${buildDir}/libs/dependencies/"task copyDependencies(type: Copy) {
from configurations.compile
into "${dependsDir}"
}
  • Execute gradle copyDependencies

You can see that the JSON lib is copied to app\build\libs\dependencies

Now we can create a task to create the runnable jar with the classpath entries in the manifest.

task createJar(dependsOn: copyDependencies, type: Jar) {   manifest {
attributes(
'Main-Class': 'com.example.gradle.App',
'Class-Path': configurations.compile.collect
{ 'dependencies/' + it.getName() }.join(' ')
)}
with jar
}
  • Execute gradle createJar
  • Run the application
java -jar app\build\libs\app.jarHello World!
{"key1":"value1","key2":"value2"}

Great !. I hope that this gradle introduction helps you to have a good understanding about the gradle build concept and will helps you to build applications.

Conclusion

  • We discussed about what is gradle and how to create simple tasks
  • Overview about gradle plugins
  • How to create a Java application without IDE and build the application
  • Create runnable jars with dependencies managed.

You can download the sample project from GitHub : https://github.com/jafarmlp/gradle-java

--

--