Using SWIG-ed libraries from Clojure

In a previous post I described a small workaround on how to use the QuantLib SWIG bindings from Clojure. It looks however that use of SWIG bindings from Clojure is of wider interest so here a more general description with also a simplified implementation.

Recap

The Java environment can have multiple class loaders and Clojure makes use of this mechanism. For this reason a Java Native Interface library loaded in Clojure through the call such as:

(System/loadLibrary "MyJNI")

will not be seen by the SWIG Java bindings which are imported using standard :import statement in Clojure. The resolution of this problem is that to ensure the JNI part of the SWIG binding is loaded directly from the SWIG Java classes rather then Clojure.

Simple Implementation

The simplest way of ensuring that this loading does in fact occur is to add a jniclasscode statement to the SWIG ".i" file. This looks something like:

 %pragma(java) jniclasscode=%{
 static {
       try { System.loadLibrary("MyJNI");
 }
 catch (RuntimeException e) {
    System.out.println("Failed to load the C++ libraries during SWIG module initialisation");
    e.printStackTrace();
}
}
%}

This code is then inserted by SWIG into the static initialisation of the Java part of the SWIG binding, ensuring that the JNI library is loaded and further more laded using the same class loader as rest of the binding.