Getting Started with Gradle: Creating a Binary Distribution
After we have created a useful application, the odds are that we want to share it with other people. One way to do this is to create a binary distribution that can be downloaded from our website.
This blog post describes how we can a binary distribution that fulfils the following requirements:
- Our binary distribution must not use so called “fat jar” approach. In other words, the dependencies of our application must not be packaged into the same jar file than our application.
- Our binary distribution must contain startup scripts for *nix and Windows operating systems.
- The root directory of our binary distribution must contain the license of our application.
Let’s get started.
Additional reading:
- Getting Started with Gradle: Introduction helps you to install Gradle, describes the basic concepts of a Gradle build, and describes how you can functionality to your build by using Gradle plugins.
- Getting Started with Gradle: Our First Java Project describes how you can create a Java project by using Gradle and package your application to an executable jar file.
- Getting Started with Gradle: Dependency Management describes how you can manage the dependencies of your Gradle project.
Creating a Binary Distribution
The application plugin is a Gradle plugin that allows us to run our application, install it, and create a binary distribution that doesn’t use the “fat jar” approach.
We can create a binary distribution by making the following changes to the build.gradle file of the example application that we created during the previous part of my Getting Started with Gradle tutorial:
- Remove the configuration of the jar task.
- Apply the application plugin to our project.
- Configure the main class of our application by setting the value of the mainClassName property.
After we have made these changes to our build.gradle file, it looks as follows (the relevant parts are highlighted):
apply plugin: 'application' apply plugin: 'java' repositories { mavenCentral() } dependencies { compile 'log4j:log4j:1.2.17' testCompile 'junit:junit:4.11' } mainClassName = 'net.petrikainulainen.gradle.HelloWorld'
The application plugin adds five tasks to our project:
- The run task starts the application.
- The startScripts task creates startup scripts to the build/scripts directory. This tasks creates startup scripts for Windows and *nix operating systems.
- The installApp task installs the application into the build/install/[project name] directory.
- The distZip task creates the binary distribution and packages it into a zip file that is found from the build/distributions directory.
- The distTar task creates the binary distribution and packages it into a tar file that is found from the build/distributions directory.
We can create a binary distribution by running one of the following commands in the root directory of our project: gradle distZip or gradle distTar. If we create a binary distribution that is packaged to a zip file, see the following output:
> gradle distZip :compileJava :processResources :classes :jar :startScripts :distZip BUILD SUCCESSFUL Total time: 4.679 secs
If we unpackage the created binary distribution created by the application plugin, we get the following directory structure:
- The bin directory contains the startup scripts.
- The lib directory contains the jar file of our application and its dependencies.
You can get more information about the application plugin by reading the Chapter 45. The Application Plugin of the Gradle User’s Guide.
We can now create a binary distribution that fulfils almost all of our requirements. However, we still need to add the license of our application to the root directory of our binary distribution. Let’s move on and find out how we can do it.
Adding the License File of Our Application to the Binary Distribution
We can add the license of our application to our binary distribution by following these steps:
- Create a task that copies the license file from the root directory of our project to the build directory.
- Add the license file to the root directory of the created binary distribution.
Let’s move on and take a closer look at these steps.
Copying the License File to the Build Directory
The name of the file that contains the license of our application is LICENSE, and it is found from the root directory of our project.
We can copy the license file to the build directory by following these steps:
- Create a new Copy task called the copyLicense.
- Configure the source file by using the from() method of the CopySpec interface. Pass the string ‘LICENSE’ as a method parameter.
- Configure the target directory by using the into() method of the CopySpec interface. Pass the value of the $buildDir property as a method parameter.
After we have followed these steps, our build.gradle file looks as follows (the relevant part is highlighted):
apply plugin: 'application' apply plugin: 'java' repositories { mavenCentral() } dependencies { compile 'log4j:log4j:1.2.17' testCompile 'junit:junit:4.11' } mainClassName = 'net.petrikainulainen.gradle.HelloWorld' task copyLicense(type: Copy) { from "LICENSE" into "$buildDir" }
Additional Information:
We have now created a task that copies the LICENSE file from the root directory of our project to the build directory. However, when we run the command gradle distZip in the root directory of our project, we see the following output:
> gradle distZip :compileJava :processResources :classes :jar :startScripts :distZip BUILD SUCCESSFUL Total time: 4.679 secs
In other words, our new task is not invoked and this naturally means that the license file is not included in our binary distribution. Let’s fix this problem.
Adding the License File to the Binary Distribution
We can add the license file to the created binary distribution by following these steps:
- Transform the copyLicense task from a Copy task to a “regular” Gradle task by removing the string ‘(type: Copy)’ from its declaration.
- Modify the implementation of the copyLicense task by following these steps:
- Configure the output of the copyLicense task. Create a new File object that points to the license file found from the build directory and set it as the value of the outputs.file property.
- Copy the license file from the root directory of our project to the build directory.
- The application plugin sets a CopySpec property called the applicationDistribution to our project. We can use it to include the license file to the created binary distribution. We can do this by following these steps:
- Configure the location of the license file by using the from() method of the CopySpec interface and pass the output of the copyLicense task as method parameter.
- Configure the target directory by using the into() method of the CopySpec interface and pass an empty String as a method parameter.
After we have followed these steps, our build.gradle file looks as follows (the relevant part is highlighted):
apply plugin: 'application' apply plugin: 'java' repositories { mavenCentral() } dependencies { compile 'log4j:log4j:1.2.17' testCompile 'junit:junit:4.11' } mainClassName = 'net.petrikainulainen.gradle.HelloWorld' task copyLicense { outputs.file new File("$buildDir/LICENSE") doLast { copy { from "LICENSE" into "$buildDir" } } } applicationDistribution.from(copyLicense) { into "" }
Additional Reading:
- The API Documentation of the doLast() action of the Task
- Section 45.5 Including other resources in the distribution of the Gradle User’s Guide
- The Groovydoc of the ApplicationPluginConvention class
When we run the command gradle distZip in the root directory of our project, we see the following output:
> gradle distZip :copyLicense :compileJava :processResources :classes :jar :startScripts :distZip BUILD SUCCESSFUL Total time: 5.594 secs
As we can see, the copyLicense task is now invoked and if we unpackage our binary distribution, we notice that the LICENSE file is found from its root directory.
Let’s move on summarize what we have learned from this blog post.
Summary
This blog post taught us three things:
- We learned that we can create a binary distribution by using the application plugin.
- We learned how we can copy a file from the source directory to the target directory by using the Copy task.
- We learned how we can add files to the binary distribution that is created by the application plugin.
If you want play around with the example application of this blog post, you can get it from Github.
Reference: | Getting Started with Gradle: Creating a Binary Distribution from our JCG partner Petri Kainulainen at the Petri Kainulainen blog. |