Saturday, June 13, 2020

Gradle plugins and the convenience to make docker images – some trivias and gotchas


Gradle is a build automation tool used primarily by Java language developers to compile and package their code. It provides a framework where different automation tasks can be delegated to plugins and these can be configured for the developer’s code repository with minimal parameters in a script. When a java project is compiled, it brings in a ton of dependencies in the form of published software components that have multiple versions. The tasks of compiling and packaging the code require changes from repository to repository based on the project source code structure and the parameters for different tasks. These parameters are specified in a gradle.properties file while the script is maintained in each subproject and the project root folder. 

Options to package the code often includes tasks such as building a regular or a fat jar – the latter is one where the components are pulled in archived into a single jar file.  The jar files can be extracted with the ‘jar’ tool and is made up of compiled classes from java code an it’s manifests. When more than one jars are packaged into an uber jar, it is called a fat jar. All jars can be published in a standard way called the maven specification where the metadata and versioning are produced in a browsable manner called the build information. Destinations where this information and the build can be uploaded include remote binary repositories such as artifactory and open-source.  A lot of attention is paid to the manner in which the code is organized and the build is produced when they are as public as open-source.  

The organization of projects and sub-projects have to be such that the enumeration of plugins, repositories, dependencies and their results have to be meticulously written otherwise getting the build script can be frustrating without the transparency and knowledge about the plugins. Fortunately, the documentation and the public forums serve well to overcome some or most of these hiccups.  Commonly encountered errors are when a plugin is not specified but the task from its declarations is invoked, stale binaries when the whole project structure is not cleaned before the build and order and positioning of the steps within the script matter when there are more than one languages involved. A common practice is to turn on the debug output mode and the stacktrace from build exceptions so that the offending task and its resolution can be found. Sometimes, this resolution is not enough because the script has no visibility into the operations of the plugins because many plugins are authored outside of those provided by the framework. One way to overcome these would be to search the issues and forums tab in the plugin repositories for the opinions and resolutions cited. 

The script itself is easy to read in the more recent versions of the gradle framework and comes with its own syntax called groovy that is acceptable both for manual builds as well as in an automated pipeline. Packaging plugins come with an additional onus for their users to know the layout that will be generated from the use of the plugin. Specifying the location, version and order requires to be repeated in each and every stage of a multi-stage build automation and mistakes in one can cascade into others. The process of narrowing down the failure while starting from clean state each time before spending time debugging it requires a little less effort than otherwise. The nine rules of debugging as proposed by David Agans could come helpful here for the most elusive problems. These include “Understand the system”, “Make it fail”, “Quit thinking and look”, “Divide and Conquer”, “Change one thing at a time”, “Keep an audit trail” and “Check the plug”, “Get a fresh view” and “If you didn’t fix it, it ain’t fixed”. 

 

No comments:

Post a Comment