JNA wrapper for ZMQ

By: on October 30, 2010

Zed Shaw’s Mongrel2 uses zeromq as the communication protocol between the web server and any custom handlers that you wish to write in the language of your choosing, including Clojure via a ring adapter. So off my fingers trotted installing all the dependencies for mongrel2, including zeromq, testing my mongrel2 by walking through the examples in the excellent manual. Now for the Clojure part and disaster! I built the Java JNI code for zeromq using make, I tried to use the Clojure ZMQ libraries but they were all written against an earlier version of the Java JNI code, so I stopped in frustration. It was quite easy to proceed by writing Clojure code directly against the Java JNI code I had compiled, but the control freak in me was thinking what happens if the JNI API changes again. At this point I started investigating JNA, which is meant to be an improvement over JNI – it looked like an improvement to me since it looked like I wouldn’t need to code any C or C++ or use make.

The C API defined by zeromq in zmq.h looked simple, all the functions had man pages and the documentation had a complete set of calling examples in C – so it looked like it would be easy. I started simply, could I call the zmq_version function:

Test that with a unit test:

I ran the unit test in the IDE and success, I ran the unit test from a shell with maven and success, it felt quite strange having to basically allocate my own memory in Java but it worked and after an evenings work I had successfully wrapped most of zmq.h with JNA and had unit tests for most of the calls. Library code shown below:

These additional classes are needed to represent structures in the C library.

An incomplete unit test:

So it worked, and was remarkably painless! In the next month or so I will test it on OS X and Windows, replicate all the examples from the zeromq documentation as unit tests, wrap it with a more Java-friendly API and place it on github, so watch this space.



  1. Tim Dysinger says:

    The Java JNI library (JZMQ) from the zeromq guys is easy enough to install. See my notes here http://github.com/dysinger/zilch/blob/master/README.org

    Also, JNA is slower than JNI.

  2. Tim Dysinger says:

    If you really want to do JNA & Clojure then why write any Java? http://github.com/Chouser/clojure-jna

  3. sustrik says:

    Is it really slower? It looks like the both bindings (JNI&JNA) are doing basically the same thing. The advantage of JNA on the other hand is that the binding code is less messy.

    Btw, what about linking the binding from zeromq.org so that people can find it?

  4. tim says:

    JZMQ is easy enough to install but as mentioned in the blog the Clojure bindings are written for an old version of JZMQ. I guess I could have tried the Clojure bindings with each revision of JZMQ until I found one that worked but that doesn’t make for a brilliant set of installation instructions for the library I eventually want to produce.

    I didn’t use clojure-jna because I also want to use ZMQ from Scala so a pure Java binding is more attractive, I can produce idiomatic Clojure and Scala bindings that build on the low level JNA wrapper. If I had used clojure-jna I would have to write Java interop code when I wanted to use it with Scala.

    I haven’t measured the performance of the JNA wrapper against the JNI implementation yet. I am using an indirect mapping for the JNA wrapper at the moment, their may be a small amount more performance to be gained by using a direct mapping with JNA.

  5. Mike says:

    Tim, I like the approach of using the JNA API – it removes the requirement of the JZMQ JNI wrapper package having to be in lockstep with the ZeroMQ mainline.
    Any progress on it?
    I would also second an earlier suggestion to link from zeromq.org

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>