Tuesday 22 July 2014

Generating an application jar using Gradle 2

In an earlier post I mentioned that my latest work project encountered some surprises when trying to bundle an application and all of its dependencies into one big jar.

Last week a colleague tried using a different Gradle plugin to generate the jar more quickly, as that had been a noticeable bottleneck in the build process.  He encountered more problems and reverted back to fatjar.

This week I stumbled across the shadowJar Gradle plugin.  From all of the description and sample configuration it looked like nearly a drop in replacement for the fatjar plugin.

Some colleagues agreed that it looked quite promising and tried it out.  It worked fine on one of our applications, but resulted in runtime failures on the other one so they abandoned this build optimisation activity.

After a little compare and contrast I found that the size of the files in META-INF/services differed.  The jar generated with the fatjar plugin had some larger files than the jar generated with the shadowJar plugin.

Tracing back through the project dependencies indicated that the missing content was from the Jersey client artifacts.  It soon became apparent that the duplicate file names across two jars wasn't intended for one to be a substitutable implementation of the other, so I looked into merging.

Sure enough, by default the fatjar plugin merges the contents of service files when generating the jar, but shadowJar does not.

A single line configuration update resulted in shadowJar producing a working jar - with a complete definition of the services.

Tuesday 15 July 2014

Why Optional in Java 8 is not Serializable

So far in my exploration of Java 8 I have encountered a couple of "why'd they do it like that?" discussions.

One particularly contentious new class is java.util.Optional.

The reasoning behind not implementing Serializable boils down to discouraging developers from misusing the concept.  It's not intended to be stored as a field value, but rather to act as a temporary representation when returning a potentially null value from a method.

See the relevant JDK 8 Developers mailing list discussion for the range of perspectives.

I suspect my current team and I may have already misused Optional - time for some refactoring...

Unexciting update: I managed to find 0 offensive usages of Optional in the current project's codebase.

Thursday 3 July 2014

If the code looks weird - it probably is

I have a good habit of examining code changes when I synchronise my codebase with the latest changes from version control.

Yesterday I noticed a one liner which included an unintuitive chaining of calls. I asked my colleague about it and we briefly jumped around the code and saw a passing functional test which supposedly indicated that all was well, and moved on.

A couple of hours later I decided to try out the application through a web browser and observed that the application would fail on any request.

I went back to the questionable code and realised that the class that contained it was not covered by any unit tests.

Half an hour or so later the component in question had its own unit tests and an additional half dozen lines of code to make it perform its intended purpose.

As with many things in life, with the benefit of hindsight I realise that I should have paid more attention to when my spidey sense told me our use of the API didn't look right.