使用 JNI 库时,Clojure REPL 上的链接器错误,但编译后的 jar 上没有
Linker error on Clojure REPL but not on compiled jar when using a JNI library
我有一个 JNI 库,包括 .jar 和 .so 文件。请注意,该库适用于 Java,而非 Clojure。现在我已经能够 运行 在 eclipse 上使用 Java 中的库编写代码。
我现在要做的是通过其 Java 互操作功能将库添加到 Clojure 上 运行。我已经通过创建一个 jar 文件成功地做到了这一点,但它在 REPL 上不起作用。
这是我目前所做的:
首先,我建立了一个 leiningen 项目并导入了带有 JNI 绑定的 jar,这样我就可以正确导入并按预期从库中查看 类。
然后,我将本机库添加到我的 LD_LIBRARY_PATH(对于 Java 中的 运行 库来说这是必需的),并且加载它似乎是即使在 REPL 上也很好(没有错误)。
此时,当尝试使用库中的任何构造函数(或函数,就此而言)时,出现链接器错误:
UnsatisfiedLinkError edu.upc.freeling.freelingJNI.new_Tokenizer(Ljava/lang/String;)J edu.upc.freeling.freelingJNI.new_Tokenizer (freelingJNI.java:-2)
请注意,同一行 运行 在 Java 和用 "lein uberjar" 生成的 Clojure jar 中都有。
我对 Clojure 还是很陌生,我不知道可能出了什么问题,看看 jar 版本如何 运行ning 就好了。
有什么线索吗?
问题是要使 leiningen 成功加载库,它必须存在于在线存储库或本地存储库中。您必须使用 Maven 为 jar 创建一个本地存储库,并在 project.clj 文件中声明 :repository 选项。 Paul Gross 在他的 blog.
上有关于如何操作的详细教程
有几种方法可以做到这一点。我认为您不需要本地存储库——至少当我上次将 JNI 与 clojure 一起使用时您不需要(但那是在 clojure 1.3 中,并且 lein 从那时起发生了一些变化)。以下堆栈溢出问题和答案可能会给您一些指导
bundle-native-jni-shared-libraries-with-clojure-libraries
经过更多调查,我终于找到了答案。问题是我正在使用 System/loadLibrary 加载库,已知它在 REPL 上无法正常工作。正确的方法是像这样使用 clojure.lang.RT/loadLibrary:
(clojure.lang.RT/loadLibrary "library_name_in_java_library_path")
来源:http://grokbase.com/t/gg/clojure/145dh2amzr/loading-native-libs-from-clojure
我有一个 JNI 库,包括 .jar 和 .so 文件。请注意,该库适用于 Java,而非 Clojure。现在我已经能够 运行 在 eclipse 上使用 Java 中的库编写代码。
我现在要做的是通过其 Java 互操作功能将库添加到 Clojure 上 运行。我已经通过创建一个 jar 文件成功地做到了这一点,但它在 REPL 上不起作用。
这是我目前所做的:
首先,我建立了一个 leiningen 项目并导入了带有 JNI 绑定的 jar,这样我就可以正确导入并按预期从库中查看 类。
然后,我将本机库添加到我的 LD_LIBRARY_PATH(对于 Java 中的 运行 库来说这是必需的),并且加载它似乎是即使在 REPL 上也很好(没有错误)。
此时,当尝试使用库中的任何构造函数(或函数,就此而言)时,出现链接器错误:
UnsatisfiedLinkError edu.upc.freeling.freelingJNI.new_Tokenizer(Ljava/lang/String;)J edu.upc.freeling.freelingJNI.new_Tokenizer (freelingJNI.java:-2)
请注意,同一行 运行 在 Java 和用 "lein uberjar" 生成的 Clojure jar 中都有。
我对 Clojure 还是很陌生,我不知道可能出了什么问题,看看 jar 版本如何 运行ning 就好了。
有什么线索吗?
问题是要使 leiningen 成功加载库,它必须存在于在线存储库或本地存储库中。您必须使用 Maven 为 jar 创建一个本地存储库,并在 project.clj 文件中声明 :repository 选项。 Paul Gross 在他的 blog.
上有关于如何操作的详细教程有几种方法可以做到这一点。我认为您不需要本地存储库——至少当我上次将 JNI 与 clojure 一起使用时您不需要(但那是在 clojure 1.3 中,并且 lein 从那时起发生了一些变化)。以下堆栈溢出问题和答案可能会给您一些指导
bundle-native-jni-shared-libraries-with-clojure-libraries
经过更多调查,我终于找到了答案。问题是我正在使用 System/loadLibrary 加载库,已知它在 REPL 上无法正常工作。正确的方法是像这样使用 clojure.lang.RT/loadLibrary:
(clojure.lang.RT/loadLibrary "library_name_in_java_library_path")
来源:http://grokbase.com/t/gg/clojure/145dh2amzr/loading-native-libs-from-clojure