17 March 2017

Lightning Memory-mapped Database on OSGi

Now and then i get what i call a niche requirement, something that does not hold to any standard or good practice. These kind of requirements are usually very development intensive, time consuming and great fun, or a real PITA when having to deal with a deadline.

I am in need of a fast, local, in process atomic counter for daily file name creation, which is thread and crash save, runs within a Java/OSGi environment and can participate in a XA transactions. The files being published are getting consumed and modified by other applications as soon as they are marked with a done file, making a stateless file counting solution impossible. A RDBMS springs to mind thinking of state, but the overhead in production is unproportional as the data generated is only valid for a short period of time and in limited scope.

After turning my toolbox upside down, finding nothing even remotely fitting this job description, I heated up the search engines ready to burn time. My data structure is simple and the amount of data generated is small so a simple key/value store should be just right. This results in a long hit list, but only few libraries support file persistence, and only one made a near perfect match: lmdb. Let me emphase, near perfect match, since it is no Java, no OSGi and has no transactional integration.

The Symas page lists wrappers, and sure enough, java is listed with a JNI implementation called lmdbjni. Strange thing is that this binary has no more Maven support for Windows, MacOS and Android from 0.4.7 onward, bummer. While browsing the github repo i stumbled (by accident via RxLMDB) upon lmdbjava supporting the latest and greatest lmdb version.

So, Java is tackled with a big thanks to the people of lmdbjava. OSGi brings its own mechanism for handeling runtime files and since version 0.0.6 of  lmdbjava the path to the lmdb binary, extracted by OSGi, can be set manually to allow the JNI part to link to it. A example bundle is on github and i leave the JCA integration as exercise.

Happy coding.

2 March 2017

Twelvemonkeys on OSGi

Using Java for working with images has never been first choice, especially if the requirement for advanced computer vision functionalities needs to be met. For these cases please study OpenCV and JavaCV.
For the more daily use cases there is of course the standard Java ImageIO, providing limited image format support. My project required extensive MTIFF with CCITT compression capabilities and the good old JAI-ImageIO seemed to be a good candidate. But MTIFF support requires some extra steps to be taken, and the 10 jear old code base is missing active development. I wanted something fresh and after some research i found myself staring at the github page of twelvemonkeys ImageIO.
TwelveMonkeys is a pure Java based collection of plugins and extensions for Java's ImageIO with few optional dependencies, and under active development. It provides all i need, with a flick of the service provider switch. But lets not make this too easy now. The library is not bundled like JAI, and since i am a heavy OSGi user i want to put it on Karaf.
The first thing to do is get the jars in a bundle, ready for Karaf deployment. The Apache-felix-maven-bundle-plugin tool brings the solution in the form of embedding dependencies, putting the twelvemonkeys jars inside of a single bundle. The registration of these plugins with ImageIO gets handled by the classloader through the javax.imageio.spi.ServiceRegistry. This is a type of Java service loader responseble for finding ImageIO extensions in the classpath under the META-INF/services folder, bringing us straight to the core of our problem. Every OSGi bundle has its own classloader, meaning any image plugin loaded in one bundle is not visible to ImageIO in others. This is also true for every other library on OSGi using the java service loader mechanism.
The OSGi Enterprise R5 ServiceLoader Mediator specs discribe a standard solution for this kind of integration problem, and the reference implementation is Apache Aries Spi Fly. Under the hood it uses some fancy runtime bytecode weaving, resulting in a short classloader switch as soon as the ImageIO Serviceregistry in a bundle starts to look for plugins on the classpath, loading the plugins from the bundle containing the twelvemonkeys embedded dependencies.
Getting the MTIFF utilities in the contrib package functional under OSGi is as simple as adding a  blueprint or declarative service to the bundle containing the twelvemonkeys jars.

Sample project on github.

Recommended reading:

OSGi Alliance javautilserviceloader in OSGi