Saturday, November 2, 2013

Finding well known resources in the JVM

by Richard Vowles

A lot of people don't seem to know this, but it is actually extremely easy to find resources in the JVM without class path scanning.

Quite a few people use a scanning library or implement one themselves (which given the number and variety of ways you can specify a classpath is always going to miss something out). But if you have a well known resource, then its pretty easy to gather up all instances of it in all of the different jars that make up your application, and this is true if you are using Groovy, Java, Scala, JPython or JRuby (or any of the others, as long as you can get access to a class loader).

Since 1.2 of Java, there has been this method in the ClassLoader interface:

    public Enumeration<URL> getResources(String name) throws IOException;

So all you need to do is call:

    getClass().getClassLoader().getResources("/META-INF/myfiles.properties")

for example and all copies of that will be returned. It may not be the most efficient implementation, but it is the most well supported and it comes straight in the JVM, no extra dependencies required.

Sunday, August 25, 2013

Groovydoc and Maven

by Richard Vowles

Groovydoc and Maven


One of the things we discovered this last week, when trying to release to Apache Maven Central, was that javadoc (which is required for every artifact that has code in it) was not being generated for our Groovy artifacts.

Now in the past, we have used GMaven, which generated stubs (albeit poorly) and those caused the javadoc to trigger off, but since we moved to the Eclipse Maven plugin, this no longer worked - it compiling them both together. So we needed to start using actual Groovydoc - and it turned out, on a brief search, that there was no Maven plugin for Groovydoc.

There was however an Ant plugin, but having an Ant script, although nice that it can be dropped back to, is usually somewhat error prone and can lead to difficult configuration problems. That seemed to be the case for the Ant plugin as well, with quite a few people not being able to get it working. One of the good things however that I discovered was that the real work was in fact done outside of the Ant Groovydoc task - it just collected the information and passed it on.

The one thing I learned however, and the reason I am writing this up, is that source paths must be relative. If you pass a path that ends up having the full path to the file in it, Groovydoc will treat it as being in the Default package - and you will get a whole lot of classes in your DefaultPackage in the generated documentation. If you encounter this problem when using Ant or Gradle, then this will be the reason - make sure you use offsets from the directory where you run the build script from.

I have sorted this problem out in the Maven build, and it will pick up all source directories that get added and include them - this means generated sources and anything you add with the build helper Maven plugin.

The documentation and source is over on Github, and the artifact is in Maven Central.

Saturday, August 10, 2013

Latest plugins on Apache Maven Central

by Richard Vowles

Blue Train Software Plugins


I've made a couple of plugins lately for the projects that we use at Group Applications at the University of Auckland. I decided they would be better as open source plugins, so I did them on my own time, and they address two aspects of the lifecycle of Maven projects that we build these days.

The Release POM Plugin

The first one,  the Release POM plugin is specifically designed to generate a single pom with all transitive dependencies resolved. All dependendencies also add an exclusion clause for all dependencies of their own.

Why? Because sometimes, particularly when you are patching a production artifact, you need to make sure all dependencies stay exactly the same, except for the one you are changing. That is to me what a patch is, and that is very hard to do, as Maven doesn't actually store the versions of the artifacts you use. 

This is exacerbated because we use version ranges, which greatly aids development, bug fixing, feature enhancement and general working within the team, but it also means you need to make sure versions are locked down once you do an actual release intended for production. 

The release pom plugin and its documentation are on Github.

The Karma Runner Plugin


This one is for our Javascript, as we use AngularJS, however it can be used with any Javascript library, it just works very well with AngularJS. It requires the use of Node JS as the Karma Runner project uses that framework. 

Much of what the Karma Runner Plugin does could be done with a considerable amount of manual setup in a Maven pom - it just assumes you are using a war or (preferably) Servlet 3 JAR setup, it scans your dependencies, unpacks the javascript, re-writes the Karma config file, brings in local developer overrides (e.g. browser setups) and runs your tests. It means with minimum fuss, and maximum compatibility, we can run our Jasmine tests for Angular JS. In our case, the definition of the plugin is in the parent of every Servlet 3 jar project, nothing else needs to be configured for an individual project.

If you use Karma in a Maven project lifecycle, it really is a useful plugin.

The Karma Runner plugin for Karma is on Github.