Pregunta

Problem Statement:

I wish to call a QuantLib Java function from a Clojure namespace, as follows:

(Date. 21 Month/September 2013)

So far, I have done the following:

$ brew install boost
$ brew install quantlib

Downloaded the generated SWIG interfaces.

Created a new Leiningen project.

Copied said interfaces into src/main/java/org/quantlib/

Added:

:jvm-opts ["-Djava.library.path=src/main/java"]
:java-source-paths ["src/main/java/"]

to my project.clj.

I have followed Bojan Nikolic's instructions on solving a very similar classloading problem, adding a class BKLoader.

When I load my core.clj file into the REPL, I get the following error:

UnsatisfiedLinkError org.quantlib.QuantLibJNI.new_Date__SWIG_1(III)J org.quantlib.QuantLibJNI.new_Date__SWIG1 (QuantLibJNI.java:-2)

Bojan Nikolic has a recommendation to handle these classloading problems that I implemented as well in trying to run this down. Per that link, I added a new static class BKLoader to load QuantLibJNI, loaded it with the other Java classes and tried loading core.clj into the REPL again, to the resounding trumpets of:

UnsatisfiedLinkError no QuantLibJNI in java.library.path java.lang.Classloader.loadLibrary (ClassLoader.java:1758)

At which point I rip out B. Nikolic's class from the ns declaration in my core.clj and take a look at classlojure.

Per Apage43's suggestion in #clojure, at this point I drop the following into my core.clj:

(classlojure/with-classloader
  (.getClassLoader Date) 
  (System/loadLibrary "QuantLibJNI"))

Which results in the same error as when calling the BKLoader class.

I appreciate any insight any of y'all can bring to bear. Thanks!

Solution

The solution is to add the QuantLib jar to :java-source-paths in project.clj:

:java-source-paths ["src/main/java" "/usr/local/lib/QuantLib.jar"]
¿Fue útil?

Solución

The error indicates that the java vm cannot find a DLL it needs.

so probably the dll it wants to load is not available in src/main/java from the directory where you launch the file as you specified it to find it via

:jvm-opts ["-Djava.library.path=src/main/java"]

Sometimes it is the dll that is not in there, but sometimes a dll also wants to load other dll's so it might be a good idea in that case to also set your environment variable PATH to point to the directories where other dll's can be loaded.

There is a tool from microsoft where you can trace the dll's being loaded or needed, one is the dependencyWalker and another is the processmonitor. Both free to download from somewhere in www.microsoft.com

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top