Java ProgrammingGradle the Modern Java Build Tool

Gradle the Modern Java Build Tool

The focus of this article is to demonstrate the utility of Gradle. We do this by building packaging and running a JavaFx application on Android.

The Gradle plugin we will use to demonstrate this is the JavaFXPorts plugin jfxmobile-plugin, winner of the Duke’s Choice Award for JavaFX code on Android.

Gradle and the jfxmobile-plugin will also enable you to build package and run a JavaFx application on the IPhone   and iOS.

This article also aims to clarify the fundamental concepts employed by Gradle and common to all java Build tools. We will use examples to   break this down into two categories.

  1. Evolution of Java Build tools

Firstly we will step through how to build, compile, package and run a simple
application with Javas first dedicated build tool Apache Ant .

Then we will step through how to build, compile, package and run a simple Scala application with Ants successor Maven.

Then in the following Advanced Example we will look for a deeper understanding of the power of Gradle by working through a simple application in terms of source code but a powerful build process made possible by the utility of the current best practices build tool Gradle.

  1. Advanced Example

We will build, compile, package and run a simple JavaFx application on Android, highlighting and analysing the complex Gradle tasks that allow the assembly and translation of Java 8 byte code to Java 6 byte code then ultimately as dalvik bytecode that will run a JavaFX rich client framework as a native application in Android.

At the completion of these examples you will be conversant with the skills and concepts of Java Build Tools. The source code for all the examples can be found here.

Build compile package and run a simple application in Ant

In the source code you will find the   ANT_BASIC module. There you can find a basic Java Application using Ant as the build tool. The build.xml file in the root directory is the configuration file. We can build, package and run the application by running what are described in the build.xml as the targets but in the schema of C type language build tools are better understood as tasks. An Ant xml target defines a task. This is a good place to start to understand Gradels architecture as Gradel is built on top of Ant and uses its ‘task’ based conceptual approach. Typing gradle -version in the shell
Top
we can see when we installed Gradle it came bundled with Ant.

Ant comes out of the box with a number of preconfigured tasks such as copy. mkdir, ect ..
We will not go too far into Ant syntax such as creating macros for chaining tasks ( <macrodef name=”buildpackage”> ) as the main focus here is Gradle, however I find it a very useful tool and use it all the time, Particularly for applications where dependency management breaks down with tools like Maven and Gradle because of ‘transitive dependency issues and the dreaded ‘NoClassDefnError’. The provided Ant template project here would be useful if you are new to Ant and want to get started using it as a build tool, it covers all the basics such as classpath for example, that you will need for building, packaging and running an application.

Build compile package and run a Scala application with Maven

In the MAVEN_INTERMEDIATE module you can find a basic Java Application with Ant as the build tool. The pom.xml file in the root directory is the configuration file where pom is an acronym for Project Object Module . Maven is a major break from Ant in the following ways

  1. Maven is an opinionated tool. It has a well defined project lifecycle and project structure that when you adhere to this structure allows for very powerful build configurations. This comes at the loss of the freedoms you have in Ant.
  2. Maven tries to take the approach of being completely declarative and forcing you to write and compile a plugin if you need logic, it defines a plug-in architecture for extended behaviour.
  3. Maven works on the idea of a repository where it stores and managed your dependencies

The MAVEN_INTERMEDIATE project/module contains equivalent functionality to the Ant module using the plugins you need for building, packaging and running an application. It uses repositories for dependency management. It has this concept of a transitive dependency. Transitivity is a powerful mechanism for dependency management however it can lead to many problems in a complex dependency graph.

We will not go into Maven syntax such as creating profiles and custom plugins. It is important for this article to highlight the issues with Java build tools, both Ant and Maven take fundamentally different approaches and each is useful in the way they will allow a certain class of Java application to build. The value here is to highlight the historical development of these tools and how Gradle has evolved to overcome the limitations found in both Maven and Ant. The MAVEN_INTERMEDIATE project/module would be useful if you are new Maven and want to get started using it as a build tool. Also it shows how you can use Maven to work with other Java Virtual Machine language such as Scala.

Build compile package and run a simple JavaFx application on Android

Gradle incorporates the best feature of both Ant and Maven. More than this Gradle put the fun back into building applications. It achieves this with Groovy and flexibility.

A quick summary Gradle’s main attributes

  • Gradle is a transitive dependency manager.
  • It allows for convention over configuration but is not restricted to convention.
  • It includes Ant tasks as first class citizens.
  • It allows you to use existing Maven / Ivy repositories
  • Using Groovy Gradle is a programming tool.

When building an application Gradle is a Groovy dependency programming tool that has two distinct phases, evaluation and execution. During evaluation Gradle will evaluate groovy scripts. During execution Gradle will run tasks which have been defined by these scripts taking into account interdependencies between them. As a programming tool Gradle gives you many more features than Maven or Ant.

As a programming tool like Ant, Gradle breaks free of convention for the project structure and it is infinitely configurable. As a programming tool Gradle is a more flexible dependency manager than Maven. Gradle works with Maven repositories but also supports other repository infrastructures.

As a programming tool Gradle can adapt to the projects structure and architecture. You don’t have to create the project in a predefined layout as would be required with Maven.

Learn Gradle by Example
In the GRADLE_ADVANCED module you can find a basic JavaFX 8 Application with Gradle as the build tool. This code can be built and packaged by Gradle to run on both Android and iOS. This is possible due to community driven innovation porting JavaFx 8 to Android and iOS JavaFX ports.

Having a single Rich application framework available for these two divergent operation systems shows the power and promise of Java dating back to Goslings original vision, which in its most simplest is Java everywhere!

We will start by building and running the application on Android. For this article we will use Intellij to illustrate the Gradle task definitions used in the build process. To achieve this you will need to have Gradle >= 2.2, Java 8 > 8u40. Import the GRADLE_ADVANCED modules build.gradle into Intellij. If you succeed in this you will see the following package structure

second from top

In the Intellij Gradle tab you will see a list of all the available Gradle tasks for the project. I have a screenshot here of some of the more important tasks that need to run in the projects build.

Fourth from top
This screenshot shows we have tasks for building and installing the Application on both iOS and Android devices. These tasks are configured in the JavaFX ports javafxmobile-plugin .

Before we discuss the plugin in depth lets first build package deploy the JavaFX source code to an Android device or emulator. Either in intellij or from the command line run the Gradle task ‘build’ followed by the’ android task’. You will then see Fig1 output. Then run the Gradle ‘androidinstall’ task and you will see Fig .

Fourth from top

When both of these tasks have executed successfully you should find the installed application in your Android device as shown in the screenshot below. It will be a similar process for IOS.

Fith  from top

This screen-shot shows the application running.

bottom image

Behind the scene Gradle via the javafxmobile-plugin ran the tasks that depend on the top level declarations that we declare in the build.gradle reproduced below

buildscript {
	repositories {
    	jcenter()
	}

	dependencies {
    	classpath 'org.javafxports:jfxmobile-plugin:1.0.0-b4'
	}
}

apply plugin: 'org.javafxports.jfxmobile'

mainClassName = 'com.eduonix.EntryPoint'
version = '8u40'

repositories {
	jcenter()
}

jfxmobile {
	ios {
    	forceLinkClasses = ['com.eduonix.**.*']
	}
	android {
    	applicationPackage = 'org.javafxports.com.eduonix'
	}
}

At a superficial level we can understand the syntax here, as with maven we are declaring repositories for dependencies and configuring things like the entry point for the application via the mainClassName attribute.

However to understand the relationships between the source code and the build process we to be aware we are running a build script with groovy closures. That is we are using a programming tool.

The top level method definitions exist in the Gradle Project class. In the Project class javadoc for the apply method we see three overloaded method signatures one of which take a closure, property or action.

We can reasonably deduce then that the syntax apply plugin: ‘org.javafxports.jfxmobile’ breaks down to apply <property> : <property> == <key, value> where the property key = ‘plugin’ and the property value =’org.javafxports.jfxmobile’ .

With this in mind we can consider the following code block for the javafxmobile-plugin

jfxmobile {
	ios {
    	forceLinkClasses = ['com.eduonix.**.*']
	}
	android {
    	applicationPackage = 'org.javafxports.com.eduonix'
	}
}

Rather than the syntax jfxmobile <closure>. we are now using a powerful feature of the Gradle DSL,   that is extensions, we find this extension in the groovy main class JFXMobilePlugin for the javafxmobile-plugin source code here.

project.extensions.create("jfxmobile", JFXMobileExtension, project)

The groovy class’s JFXMobileExtension define further extensions AndroidExtension and IosExtension to drive the Android and iOS build flow.

In the JFXMobilePlugin class definition we see it asks for an instance of the Project class created by this particular Gradle build script.

class JFXMobilePlugin implements Plugin

The interface method definition Plugin.apply() that is called from the build script declaration

void apply(Project project) { …..

applies the plugins used in this plugin notably

project.plugins.apply JavaPlugin
project.plugins.apply ApplicationPlugin
project.plugins.apply RetrolambdaPlugin

Here the RetrolambdaPlugin translates the java bytecode to Java 6, the Java and Application plugins are used to set up a Java project as an Application available for the ‘run’ task.

Once you get a handle on the relationship between the build script declared in the project and the gradle Project.class and Plugin interface the syntax is clear and with the excellent Gradle documentation it is easy to see why the developers at JavaFx Ports chose to implement the Gradle build tool for this innovative and complex operation, that is to build, package and deploy a JavaFx application to Android and iOS.

It is hoped the supplied source code and introduction to Gradle will be useful in kickstarting projects if you are new to Java Build tools.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Exclusive content

- Advertisement -

Latest article

21,501FansLike
4,106FollowersFollow
106,000SubscribersSubscribe

More article

- Advertisement -