Jawa

Ant vs Maven vs Gradle

Ant vs Maven vs Gradle

Choosing the Right Build Tool: Ant vs Maven vs Gradle

During software development, developers have to rebuild the same code over and over again. They often try to use bash scripts or other scripting languages to automate the task. However, there are build tools available that are more appropriate for build automation. The predominant build tools are:

Let's investigate the tools to find out more.

Apache Ant with Ivy

Apache Ant is a Java-based command line tool that uses XML files to define build scripts. It's predominantly used for Java builds but it can also be used for C/C++ development. Built-in tasks provide ways to compile, assemble, test and run software applications. Users can also create their own “antlibs” to enhance the functionality of Ant. Apache Ivy is a dependency management tool that integrates easily with Ant to provide a more robust ecosystem. The development of Ant started in 2000.

Pros

Cons

Ant with Ivy Example

You can install the latest Ant from here. You have to download the zip, expand and put the bin folder in your path. You can use the following command to see if Ant is installed properly:

$ ant -version
Apache Ant(TM) version 1.10.1 compiled on February 2 2017

Once you have Ant installed, you can download the latest Ivy jar and put it in the lib folder inside the Ant directory.

After you have Ant installed, create folders helloworld and helloworld/src. Inside the src folder, put helloworld.java file with the code:

/**************************
Prints Out "Hello World!"
***************************/
public class helloworld
public static void main(String[] args)
System.out.println("Hello World!");

Now in the helloworld folder create a build.xml file with the following code:
























And in the same helloworld folder, create the ivy.xml file with the following code:






The directory structure should look like this:

helloworld
|-- build.xml
|-- ivy.xml
'-- src
'-- helloworld.java

Now you can run the build with the command:

$ ant jar

A successful build should provide output like this:

$ ant jar
Buildfile: /Users/zak/_work/LearnBuildScripts/LearnANT/helloworld/build.xml
resolve:
[ivy:retrieve] :: Apache Ivy 2.4.0 - 20141213170938 :: http://ant.apache.org/ivy/ ::
[ivy:retrieve] :: loading settings :: url = jar:file:/Users/zak/BuildTools/ANT/apache
-ant-1.10.1/lib/ivy-2.4.0.jar!/org/apache/ivy/core/settings/ivysettings.xml
[ivy:retrieve] :: resolving dependencies :: org.apache#helloworld;[email protected]
MacBook-Air.local
[ivy:retrieve]     confs: [default]
[ivy:retrieve]     found junit#junit;4.12 in public
[ivy:retrieve]     found org.hamcrest#hamcrest-core;1.3 in public
[ivy:retrieve] :: resolution report :: resolve 397ms :: artifacts dl 15ms
---------------------------------------------------------------------
|                  |            modules            ||   artifacts   |
|       conf       | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
|      default     |   2   |   0   |   0   |   0   ||   4   |   0   |
---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: org.apache#helloworld
[ivy:retrieve]     confs: [default]
[ivy:retrieve]     0 artifacts copied, 4 already retrieved (0kB/39ms)
compile:
[mkdir] Created dir: /Users/zak/_work/LearnBuildScripts/LearnANT/helloworld/build/
classes
[javac] /Users/zak/_work/LearnBuildScripts/LearnANT/helloworld/build.xml:22: warning:
'includeantruntime'was not set, defaulting to build.sysclasspath=last; set to false
for repeatable builds
[javac] Compiling 1 source file to /Users/zak/_work/LearnBuildScripts/LearnANT/
helloworld/build/classes
jar:
[mkdir] Created dir: /Users/zak/_work/LearnBuildScripts/LearnANT/helloworld/build/bin
[jar] Building jar: /Users/zak/_work/LearnBuildScripts/LearnANT/helloworld/build/bin/
helloworld.jar
BUILD SUCCESSFUL
Total time: 6 seconds

You can try out the jar file like this:

$ java -cp build/bin/helloworld.jar helloworld
Hello World!

We have defined the jar file to be put in the build/bin folder. The folders get created during the build. The ant jar command calls the jar target in the build.xml.

Maven

Maven was developed to resolve the problems faced with Ant-based scripting. It kept the XML files but took a different approach to organization. In Ant, developers have to create all the tasks. Maven decreases the task creation by implementing stronger standards for organizing code. As a result, it's easier to get started on standard projects.

It also introduced dependency downloads which made the development easier. Before the introduction of Ivy in Ant, users had to manage dependencies locally. Maven adopted the dependency management philosophy first.

However, Mavens strict standards make it difficult to write custom build scripts. The tool is easy to work with as long as the project follow the strict standards.

Pros

Cons

Maven Example

You can download the latest Maven from here. You can check the installation like this:

$ mvn --version
Apache Maven 3.5.2 (138edd61fd100ec658bfa2d307c43b76940a5d7d; 2017-10-18T00:58:13-07:00)
Maven home: /Users/zak/BuildTools/Maven/apache-maven-3.5.2
Java version: 1.8.0_74, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_74.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.11.6", arch: "x86_64", family: "mac"

Create a helloworld folder and generate a project with the following command:

$ mvn archetype:generate -DgroupId=com.companyname.helloworld -DartifactId=helloworld
-DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

It should create the folder structure and generate the output that looks like this:

[INFO] Scanning for projects…
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] >>> maven-archetype-plugin:3.0.0:generate (default-cli) > generate-sources
@ standalone-pom >>>
[INFO]
[INFO] <<< maven-archetype-plugin:3.0.0:generate (default-cli) < generate-sources
@ standalone-pom <<<
[INFO]
[INFO]
[INFO] --- maven-archetype-plugin:3.0.0:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Batch mode
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Old (1.x) Archetype:
maven-archetype-quickstart:1.0
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: basedir, Value: /Users/zak/_work/LearnBuildScripts/LearnMaven
[INFO] Parameter: package, Value: com.companyname.helloworld
[INFO] Parameter: groupId, Value: com.companyname.helloworld
[INFO] Parameter: artifactId, Value: helloworld
[INFO] Parameter: packageName, Value: com.companyname.helloworld
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: /Users/zak/_work/
LearnBuildScripts/LearnMaven/helloworld
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.602 s
[INFO] Finished at: 2018-01-27T00:05:37-08:00
[INFO] Final Memory: 15M/152M
[INFO] ------------------------------------------------------------------------

The folder structure should look like this:

helloworld
|-- pom.xml
'-- src
|-- main
| '-- java
| '-- com
| '-- companyname
| '-- helloworld
| '-- App.java
'-- test
'-- java
'-- com
'-- companyname
'-- helloworld
'-- AppTest.java

The pom.xml contains the build configurations. Inside the pom.xml the code looks like this:

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0
_0.xsd">
4.0.0
com.companyname.helloworld
helloworld
jar
1.0-SNAPSHOT
helloworld
http://maven.apache.org


junit
junit
3.8.1
test


You can generate the jar file using the following command:

$ mvn package
[INFO] Scanning for projects…
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building helloworld 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ helloworld ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e.
build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/zak/_work/LearnBuildScripts/LearnMaven/
helloworld/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ helloworld ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is
platform dependent!
[INFO] Compiling 1 source file to /Users/zak/_work/LearnBuildScripts/LearnMaven/
helloworld/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @
helloworld ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e.
build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/zak/_work/LearnBuildScripts/LearnMaven/
helloworld/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ helloworld ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is
platform dependent!
[INFO] Compiling 1 source file to /Users/zak/_work/LearnBuildScripts/LearnMaven
/helloworld/target/test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ helloworld ---
[INFO] Surefire report directory: /Users/zak/_work/LearnBuildScripts/LearnMaven
/helloworld/target/
surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.companyname.helloworld.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.014 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ helloworld ---
[INFO] Building jar: /Users/zak/_work/LearnBuildScripts/LearnMaven/helloworld/target/
helloworld-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.624 s
[INFO] Finished at: 2018-01-27T00:11:10-08:00
[INFO] Final Memory: 16M/114M
[INFO] ------------------------------------------------------------------------

You can run the jar file like this:

$ java -cp target/helloworld-1.0-SNAPSHOT.jar com.companyname.helloworld.App
Hello World!

The jar file is put in the target folder.

Gradle

Gradle combines the power of Ant and Maven. The first version of Gradle was released in 2012. It has seen fast adoption. Google is currently using it for Android OS.

Instead of XML, Gradle uses the Groovy language. As a result, build scripts in Gradle are easier to write and read. It was initially using Ivy for dependency management, but it is using its own dependency engine now.

Pros

Cons

Gradle Example

You can install Gradle from here. Once you set up Gradle in your path, you can check it by:

$ gradle --version
------------------------------------------------------------
Gradle 4.5
------------------------------------------------------------
Build time:   2018-01-24 17:04:52 UTC
Revision:     77d0ec90636f43669dc794ca17ef80dd65457bec
Groovy:       2.4.12
Ant:          Apache Ant(TM) version 1.9.9 compiled on February 2 2017
JVM:          1.8.0_74 (Oracle Corporation 25.74-b02)
OS:           Mac OS X 10.11.6 x86_64

Next, create the following directory structure:

helloworld
|-- build.gradle
'-- src
|-- main
'-- java
'-- helloworld
'-- helloworld.java

For the helloworld.java put the code from the Ant example. And for build.gradle put in the following code:

apply plugin: 'java'
version = '1.0'
repositories
mavenCentral()

dependencies
testCompile group: 'junit', name: 'junit', version: '4.12'

You can use “gradle tasks -all” command to look at all the commands available. Gradle automatically picks up the plugins you specify in the build.gradle file and shows you the extra tasks available due to the plugins.

You can get the build by running:

$ gradle jar
BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed

You can run your jar like this:

$ java -cp build/libs/helloworld-1.0.jar helloworld
Hello World!

The jar file is put in the build/libs folder.

Conclusion

Among the build tools, Ant can be useful for smaller projects while Maven is better for making sure all developers follow the same rules. Gradle is the latest tool that provides the most flexibility.

References:

Gry SuperTuxKart for Linux
SuperTuxKart for Linux
SuperTuxKart is a great title designed to bring you the Mario Kart experience free of charge on your Linux system. It is pretty challenging and fun to...
Gry Battle for Wesnoth Tutorial
Battle for Wesnoth Tutorial
The Battle for Wesnoth is one of the most popular open source strategy games that you can play at this time. Not only has this game been in developmen...
Gry 0 A.D. Tutorial
0 A.D. Tutorial
Out of the many strategy games out there, 0 A.D. manages to stand out as a comprehensive title and a very deep, tactical game despite being open sourc...