1
votes

I have a JNI library, both .jar and .so files. Note that the library is intended for Java, not Clojure. Right now I've been able run code using the library in Java, on eclipse.

What I'm trying to do now is getting the library to run on Clojure by means of its Java interop capabilities. I've been successful in doing so by creating a jar file, but it's not working on the REPL.

Here's what I've done so far:

  • First, I've set up a leiningen project and imported the jar with the JNI bindings so I could properly import and see the classes from the library as expected.

  • Then, I added the native library to my LD_LIBRARY_PATH (that's necessary for that library to run in Java), and loading it seems to be just fine (no errors) even on the REPL.

At this point, when trying to use any constructor (or function, for that matter) from the library, I get linker errors:

UnsatisfiedLinkError edu.upc.freeling.freelingJNI.new_Tokenizer(Ljava/lang/String;)J  edu.upc.freeling.freelingJNI.new_Tokenizer (freelingJNI.java:-2)

Note that that same line runs both on Java and in a Clojure jar generated with "lein uberjar".

I'm still quite new to Clojure and I don't know what could possibly be wrong, seeing how the jar version is running just fine.

Any clues?

3

3 Answers

0
votes

The problem is that for leiningen to successfully load a library it has to exist on a online repository or a local repository. You'll have to create a local repository for the jar using maven and declare the :repository option in your project.clj file. Paul Gross has a detailed tutorial on how to do it on his blog.

0
votes

There are a couple of ways to do this. I don't believe you need a local repository - at least you didn't when I last used JNI with clojure (but that was back with clojure 1.3 and lein has changed a bit since then). The following stack overflow question and answer might give you some pointers

bundle-native-jni-shared-libraries-with-clojure-libraries

0
votes

After some more investigation, I've finally found the answer. The thing is I was using System/loadLibrary to load the library, which is known to not work properly on the REPL. The proper way was to use clojure.lang.RT/loadLibrary like so:

(clojure.lang.RT/loadLibrary "library_name_in_java_library_path")

Source: http://grokbase.com/t/gg/clojure/145dh2amzr/loading-native-libs-from-clojure