Thursday, September 20, 2018

Create jar using gradle and setting Main class

Our build script must create an executable jar file. In other words, we must be able to run our program by using the command:
java -jar jarfile.jar
Let’s find out how we can fulfil this requirement.

Creating a Java Project

We can create a Java project by applying the Java plugin. We can do this by adding the following line to our build.gradle file:
1
apply plugin: 'java'

The Project Layout of a Java Project

  • The src/main/java directory contains the source code of our project.
  • The src/main/resources directory contains the resources (such as properties files) of our project.
  • The src/test/java directory contains the test classes.
  • The src/test/resources directory contains the test resources.
All output files of our build are created under the build directory. This directory contains the following subdirectories which are relevant to this blog post (there are other subdirectories too, but we will talk about them in the future):
  • The classes directory contains the compiled .class files.
  • The libs directory contains the jar or war files created by the build.
Let’s move on and add a simple main class to our project.

Adding a Main Class to Our Build

Let’s create a simple main class which prints the words: “Hello World” to System.out. The source code of the HelloWorld class looks as follows:
1
2
3
4
5
6
7
8
package hello;
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}





The Tasks of a Java Project

The Java plugin adds many tasks to our build but the tasks which are relevant for this blog post are:
  • The assemble task compiles the source code of our application and packages it to a jar file. This task doesn’t run the unit tests.
  • The build task performs a full build of the project.
  • The clean task deletes the build directory.
  • The compileJava task compiles the source code of our application.
We can also get the full list of runnable tasks and their description by running the following command at the command prompt:
gradle tasks


> gradle build


  • The assemble task runs only the tasks which are required to package our application.
  • The build task runs the tasks which are required to package our application AND runs automated tests.

We can now try to run our application by using the following command:
java -jar first-java-project.jar
When we do this, we see the following output:
> java -jar first-java.project.jar
No main manifest attribute, in first-java-project.jar
The problem is that we haven’t configured the main class of the jar file in the manifest file. Let’s find out how we can fix this problem.

Configuring the Main Class of a Jar File

The Java plugin adds a jar task to our project, and every jar object has a manifest property which is an instance of Manifest.
We can configure the main class of the created jar file by using the attributes() method of the Manifestinterface. In other words, we can specify the attributes added to the manifest file by using a map which contains key-value pairs.
We can set the entry point of our application by setting the value of the Main-Class attribute. After we have made the required changes to the build.gradle file, its source code looks as follows (the relevant part is highlighted):
1
2
3
4
5
6
7
apply plugin: 'java'
jar {
    manifest {
        attributes 'Main-Class': 'net.petrikainulainen.gradle.HelloWorld'
    }
}



> java -jar first-java-project.jar
Hello World!



You can see the below addition to Manifest file

Manifest.MF


Manifest-Version: 1.0 Main-Class: hello.HelloWorld