Friday 23 January 2015

Assembling a jar to include dependencies with Gradle

How to build a jar containing dependency jars with Gradle

As part of a hack day project at work I have started developing a plugin for use with ThoughtWorks Go CD.

After some initial confusion around how Go Server expects to find the plugin bundled, I realised that a jar file containing a lib folder of jars is the way to make it work.

The example plugins GitHub repository only showed the use of Maven as a project build tool, but I have gotten accustomed to using Gradle - so I need to do a bit of reverse engineering and searching online to find a way to produce a suitable jar to include the managed dependencies of my project.

Without further ado, here is the relevant snippet of Gradle configuration:

jar {
    into('lib') {
        from configurations.runtime

This simply creates a lib directory within the generated jar.  The lib directory will contain the various jars that are pulled in by the managed dependencies.  By default this will include transitive dependencies.

This works with Gradle 2.2.1 and I would expect it to work for earlier versions.

Thursday 15 January 2015

Basic readiness check before developing with micro services - DNS

So, you have your application nicely sliced up into purposeful, self-contained units which can call upon each-other as required - great.

Presuming each of these components is communicating over http, how are you going to deploy them and make them accessible to each other?  Why not use a beautiful Platform As A Service environment - developers can deploy new apps, and manage existing apps to their hearts' content without any assistance from other teams.  Lovely.

Ok, let's presume that your setup has big ambitions and limited IP addresses so you're going to need these applications to have hostnames.  No big deal, and easier to quickly verify what is what.  Who would use IP addresses directly - this is the 21st century!

What if DNS hasn't been set up to cope with some additional load.  It only craps out every other week, but when it does your applications can't reach each other.  Deployments fail, developers get stalled tracking down problems that they haven't caused.  Live demonstrations are now considered risky.

Welcome to my world.  It's the third or fourth time that I've bugged a team that should be able to trace this problem and arrange for it to be fixed (even temporarily).  Their response is that the impact seems to be broader than the single host that the app is currently complained about.  Their recommendation is to update the app's config with IP addresses for a while.

We have a central configuration system, but I don't think it is intended to act as a replacement for an /etc/hosts file.

After publicly lecturing me about how the configuration management system should make dirty hacks like this (I'm paraphrasing) possible, they contacted someone who could flush a cache or restart the misbehaving service to solve the problem temporarily.

Sunday 4 January 2015

Career safety checkpoint

As another year begins, I found myself struggling to get to sleep before the first day back at work.  This wasn't a new experience for me as I seem to recall the same sort of nervousness before the first day back at school as a child.

I consider this time of year to be a bit like travelling between very different timezones - just as I have gotten accustomed to going to bed late and sleeping late the following morning, it's time to adjust back to the work life routine.

One of the many thoughts that occurred to me when I should have been blissfully sleeping was whether my skills are still as relevant to my chosen career in software development.

In the morning I woke up early and decided to have a look at some source code from a system that my current project will be interacting with...

A section of code that particularly stood out to me involved something like 12 branches of if / else checks, where each comparison was against a constant defined earlier in the class, and each outcome also involved another constant.  This could easily be condensed down to two or three lines with one conditional expression by replacing all of the constants with a single Map.

I'm sleeping much better.