Showing posts with label build. Show all posts
Showing posts with label build. Show all posts

Thursday, December 14, 2017

Build Tools in Java World

Build tools in Java (or JVM ecosystem) have evolved over period of time. Each successive build tool has tried to solve some of the pains of the previous one. But before going further down on tools, let’s start with basic features of standard build tools. 

Dependency Management
Each project requires some external libraries for build to be successful.  So these incoming files/jars/libraries are called as dependencies of the project.  Managing dependencies in a centralized manner is de-facto feature of modern build tools.  Output artifact of the project also gets published and then managed by dependency management. Apache IVY and Maven are two most popular tools which support dependency management.

Build By Convention
Build script needs to be as simple and compact as possible. Imagine specifying each and every action which needs to be performed during build (compile all files from src directory, copy them to dir file, create jar file and so on); this will definitely make the script huge and hence managing and evolving it becomes a daunting task. So, modern build tools uses convention like by default (or can be configured as well) it knows that source files are in src directory. This minimizes number of lines in the build file and hence it becomes easier to write and manage build scripts.  
So any standard build tool should have above two as de-facto. Below are list of tools which have these features.


ANT + IVY (Apache IVY for dependency management)
·         MAVEN
·         GRADLE

I have listed only most popular build tools above. ANT by default doesn’t have dependency management but other two have native support for dependency management. Java world is basically divided between MAVEN and GRADLE.  So, I have focused below on these two tools.


Maven vs Gradle

  • MAVEN uses XML to write build script where as GRADLE uses a DSL language based on Groovy (one of the JVM language). GRADLE build script tends to be shorter and cleaner compared to maven build script.
  • GRADLE build script is written in Groovy (and can also be extended using Java). This definitely gives more flexibility to customize the build process. Groovy is a real programming language (unlike XML). Also, GRADLE doesn’t force to always use convention, it can be overridden. 
  • GRADLE has first class support for multi-project build whereas multi-project build of MAVEN is broken. GRADLE support dependency management natively using Apache open source project IVY (is an excellent dependency management tool).  Dependency management of GRADLE is better than MAVEN.
  • MAVEN is quite popular tool so it has wide community and Java community have been using it for a while; GRADLE on the other hand is quite new so there will be learning curve for developers.
  • Both are plugin based (and GRADLE being a newer); finding plugin might be difficult for GRADLE. But adoption of GRADLE is growing at good pace, Google supports GRADE for Android. Integration of GRADLE with servers, IDEs and CI tools is not as much as that of MAVEN (as of now).


  • CONCLUSION

    Most of the cons for GRADLE are mainly because it’s a new kid in the block. Other than this, rest all looks quite impressive about GRADLE. It scores better on both core features i.e. Dependency Management and Build by Convention. IMO, configuring build through a programming language is going to be more seamless once we overcome the initial learning curve.
    Also, considering we are going down the microservices path, so we will have option and flexibility to experiment with build tool as well (along with language/framework).

    References

    https://github.com/tkruse/build-bench





Wednesday, July 20, 2016

Gradle - Create Java Project Structure

Gradle Init plugin can be used to bootstrap the process of creating a new Java, Groovy or Scala project. This plugin needs to be applied to a project before it can be used. So if we want to create default directory structure of a Java project this plugin can be handy (Especially if you don't have Gradle plugin in your IDE).

$gradle init --type java-library

The init plugin supports multiple types (it's 'java-library' in above command). Below are the command sequence and directory which gets created after successful execution.


$ mkdir hello-gradle
$ cd hello-gradle/
$ gradle init --type java-library
:wrapper
:init

BUILD SUCCESSFUL


Total time: 8.766 secs

$ ls -ltr
total 20
drwxrwxr-x. 3 vagrant vagrant   20 Jul 20 06:00 gradle
-rwxrwxr-x. 1 vagrant vagrant 5080 Jul 20 06:00 gradlew
-rw-rw-r--. 1 vagrant vagrant 2404 Jul 20 06:00 gradlew.bat
-rw-rw-r--. 1 vagrant vagrant  643 Jul 20 06:00 settings.gradle
-rw-rw-r--. 1 vagrant vagrant 1212 Jul 20 06:00 build.gradle
drwxrwxr-x. 4 vagrant vagrant   28 Jul 20 06:00 src
-- 

So above command also installs the other Gradle dependencies to run the build (i.e. gradl, gradlew.bat). If you don't know what the appropriate type for your project, specify any value then it will list valid types.

$ gradle init --type something

Execution failed for task ':init'.
> The requested build setup type 'something' is not supported. Supported types: 'basic', 'groovy-library', 'java-library', 'pom', 'scala-library'.
--

So, if you just type any random text as type; Gradle tells the allowed types.

If you just use $gradle init , then gradle tries (it's best) to automatically detect the type. If it fails to identify the type, then applies basic type. 

Importing Gradle Project to Eclipse

Note that, above command created gradle specific files along with default java directories (like src) but it didn't create eclipse specific files. This means, if you try to import above created project in eclipse it will not work. To achieve that, do below:
  1. Add eclipse plugin in gradle build file (i.e. build.gradle).  Put below after java plugin. 
          apply plugin: 'eclipse'
  1. Run $gradle eclipse

This basically creates files - .classpath, .project and .settings

Now, you are good to import above project in eclipse.

Alternatively, you can clone from my GitHub repository. 


---
Happy coding !!!


Saturday, April 25, 2015

Ant Cheat Sheet

This post list some of the commonly used ant commands and shortcuts.

Test if ant is installed
$ant -version
Ant is a command-line tool so it must be on the path to be used. If Ant is installed, above command will return version details otherwise it will say that ant command is not found (i.e. Ant is not installed).

It gives below response when I run it on my Mac:
Apache Ant(TM) version 1.9.2 compiled on July 8 2013

Running ant target(s)
$ant                                     //runs default target
$ant compile                       //runs compile target
$ant <target1> <target2>    //runs multiple targets

Generate verbose log during build
$ant -verbose        //runs default target in verbose mode
$ant <target> -verbose
$ant <target> -v   // v is shortcut for verbose
Ant produces verbose log when invoked with -verbose (or -v) parameter. This is useful to figure out what's going out during build and specially when build fails.

Generate debug log during build
$ant -debug                 //runs default target in debug mode
Debug prints more log information than verbose. This option prints lot more low-level details along with verbose details.
$ant -quiet                  //to see nothing but errors and final build status message
$ant -keep-going        //tells ant to try to recover from failure

List all targets
$ant -projecthelp        //or -p
$ant -p -verbose         // list sub-targets as well
Lists all the targets provided by build file. Ant list only public targets with optional description attribute. To see optional targets also along with main targets run above command with -verbose.

Pass a property dynamically

$ant execute -Dproperty=value
Passes a key value (property) pair to the ant build. This will override if the property already exist in the build or config file.

Get build sequence
Target dependency is transitive. So if the build file is quite huge then knowing the dependency becomes quite difficult. To get it, I often run the build in verbose mode and then grep for the given String.

$ant -v main | grep "Complete build sequence is"
Complete build sequence is [clean, compile, execute, main, ]

Help
$ant -help     //or -h
If you don't remember this cheat sheet, just ask ant to help. It will give all the options which ant supports. I have covered some of them here, but some other useful options like providing your own build file other than build.xml etc are not covered here.