Simplify your script build with Gradle

Otavio Santana
Developer Relations
05 Sep 2019

Gradle is an open-source build automation system that builds upon the concepts of Apache Ant and Apache Maven, and introduces a Groovy-based, domain-specific language (DSL), instead of the XML form used by Apache Maven to declare the project configuration. This post will cover how easy it is to use this tool, and how to migrate your Maven project to Gradle to run it on Platform.sh.

Gradle is an excellent build tool with which we can automate Java applications using a clean DSL. But it’s essential to mention that Maven is still a valid and mature tool, and Gradle doesn’t deprecate Maven. There are several tutorials where both devices are compared, and you can see several companies going back and forth between Maven and Gradle. The answer to which one is the better tool is still uncertain. What matters is that at Platform.sh, you can choose both to move your Java application to the cloud.

In the Maven project, we have the pom.xml file, where we define the library dependencies, plug-ins, and so on. In a Gradle project, we have the build.gradle file. The build file for Gradle is based on DSL. In this file, you can use a combination of declarative and imperative statements. And you can write Groovy or Kotlin code, whenever you need to. Tasks can also be created and extended dynamically at runtime.

The build settings for the code with Gradle are easy! To show you how, let’s work on the demo that uses Spring Boot with Maven and migrate it to Gradle.

We won’t change the code structure, just the build settings. As a reminder and for comparison, the pom.xml is:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.mycompany</groupId>
    <artifactId>template-spring-boot-maven-mysql</artifactId>
    <version>0.0.1</version>
    <properties>
   	 <java.version>1.8</java.version>
    </properties>
    <parent>
   	 <groupId>org.springframework.boot</groupId>
   	 <artifactId>spring-boot-starter-parent</artifactId>
   	 <version>2.1.5.RELEASE</version>
    </parent>
    <dependencies>
   	 <dependency>
   		 <groupId>org.springframework.boot</groupId>
   		 <artifactId>spring-boot-starter-web</artifactId>
   	 </dependency>
   	 <dependency>
   		 <groupId>org.springframework.boot</groupId>
   		 <artifactId>spring-boot-starter-data-jpa</artifactId>
   	 </dependency>
   	 <dependency>
   		 <groupId>mysql</groupId>
   		 <artifactId>mysql-connector-java</artifactId>
   	 </dependency>
   	 <dependency>
   		 <groupId>sh.platform</groupId>
   		 <artifactId>config</artifactId>
   		 <version>2.2.2</version>
   	 </dependency>
    </dependencies>

    <build>
   	 <finalName>spring-boot-maven-mysql</finalName>
   	 <plugins>
   		 <plugin>
       		 <groupId>org.springframework.boot</groupId>
       		 <artifactId>spring-boot-maven-plugin</artifactId>
   		 </plugin>
   	 </plugins>
    </build>

    <repositories>
   	 <repository>
   		 <id>oss.sonatype.org-snapshot</id>
   		 <url>http://oss.sonatype.org/content/repositories/snapshots</url>
   	 </repository>
    </repositories>
</project>

The new settings file, as a Gradle within build.gradle, is more natural and less repetitive.

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

bootJar {
	baseName = 'spring-boot-gradle-mysql'
}

repositories {
	mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
	compile("org.springframework.boot:spring-boot-starter-web")
	compile("org.springframework.boot:spring-boot-starter-data-jpa")
	compile("mysql:mysql-connector-java")
	compile("sh.platform:config:2.2.2")
	testCompile("junit:junit")
}

buildscript {
	repositories {
    	mavenCentral()
	}
	dependencies {
    	classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.5.RELEASE")
	}
}

Gradle also supports a file-to-list properties, such as the file name: the settings.gradle. On our sample, we’re going to put the project’s file name.

rootProject.name = 'spring-boot-gradle-mysql'

To test the build, execute the command:

gradle clean build
BUILD SUCCESSFUL in 1s
4 actionable tasks: 4 executed

You can download and install Gradle locally, or by using the Gradle Wrapper. The recommended way to execute any Gradle build is with the help of the Gradle Wrapper. The Wrapper is a script that invokes a declared version of Gradle, downloading it beforehand, if necessary. As a result, you can get up and running with a Gradle project quickly without having to follow manual installation processes, saving your company time and money.

Only the developer who creates the Gradle Wrapper must have Gradle installed locally. Once the Gradle is ready, no one on the team, even the developer who creates the Wrapper, requires the native Gradle:

gradle wrapper

Once that’s done, the next developer won’t need to install Gradle again. The script has created the Gradle folder and two script files: one for Windows, gradlew.bat, and the other for Linux, gradlew.

On Platform.sh, we need to update the .platform.app.yaml file, where we define how the application builds and executes the project, which differs from the previous post.

# This file describes an application. You can have multiple applications
# in the same project.
#
# See https://docs.platform.sh/user_guide/reference/platform-app-yaml.html

# The name of this app must be unique within a project.
name: app

# The runtime the application uses.
type: "java:8"

disk: 1024

# The hooks executed at various points in the lifecycle of the application.
hooks:
  build: ./gradlew clean build --no-daemon


# The relationships of the application with services or other applications.
#
# The left-hand side is the name of the relationship as it will be exposed
# to the application in the PLATFORM_RELATIONSHIPS variable. The right-hand
# side is in the form `<service name>:<endpoint name>`.
relationships:
  database: "database:mysql"

# The configuration of the app when it is exposed to the web.
web:
  commands:
    	start:  java -jar build/libs/spring-boot-gradle-mysql.jar --server.port=$PORT

Well done! Now we have a project migrated and ready to use in Gradle. As a matter of fact, Platform.sh has a template that runs both Gradle and Spring Boot to help you create and run a Gradle project faster.