We’ve recently begun developing applications in the Clojure language that make use of the QuantLib libraries through the Java bindings (see for example here ). Using Clojure has substantial advantages about which I hope to write more about later, but in the mean time here is how to overcome an initial problem.

Class Loaders

Java Virtual Machine supports multiple class loaders. In many Java applications all the user code is loaded simply through the single “system” class loader and therefore many Java users never discover the features and problems of having multiple class loaders.

However, in order to support its interactive development environment, Clojure installs uses its own class loader. Libraries loaded by a class always get loaded by that class’s loader and this means that any libraries loaded by for example:

       (System/loadLibrary "QuantLibJNI")

will be loaded into the Clojure class loader. The implication of that is that they will not be visible in the system class loader in which QuantLib Java packages will be loaded and therefore a java.lang.UnsatisfiedLinkError error will be raised. See here for a further explanation of this effect.

Solution

The solution is to ensure that the JNI library gets loaded by the same class loader which loads SWIG-generated Java code. The simple way to do that is to add a simple class to the QuantLib jar with following structure:


     package org.quantlib;                                                                                                                                  
                                                                                                                                                            
     public class BNLoader {                                                                                                                                
                                                                                                                                                            
         static { // Load QuantLib                                                                                                                          
             try {                                                                                                                                          
                 System.loadLibrary("QuantLibJNI");                                                                                                         
             } catch (RuntimeException e) {                                                                                                                 
                 e.printStackTrace();                                                                                                                       
             }                                                                                                                                              
         }                                                                                                                                                  
     }

This trivial class has a static initialise which loads the required JNI library. Since this class is part of the QuantLib jar it is loaded by the same class loader as the the SWIG generated code and therefore it is guaranteed that the SWIG code can see the JNI library it requires to function.

For more information on QuantLib (see our dedicated pages)[https://bnikolic.co.uk/ql/].