【问题标题】:Linker error on Clojure REPL but not on compiled jar when using a JNI libraryClojure REPL 上的链接器错误,但在使用 JNI 库时编译的 jar 上没有
【发布时间】:2015-10-27 18:30:46
【问题描述】:

我有一个 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 版本的运行情况如何。

有什么线索吗?

【问题讨论】:

    标签: java clojure java-native-interface leiningen read-eval-print-loop


    【解决方案1】:

    问题是 leiningen 要成功加载库,它必须存在于在线存储库或本地存储库中。您必须使用 maven 为 jar 创建一个本地存储库,并在 project.clj 文件中声明 :repository 选项。 Paul Gross 在他的blog 上有详细的教程。

    【讨论】:

    • 感谢您的回答,但恐怕我已经按照您在询问之前提到的博客中的步骤完成了该操作。问题发生在最后。不过,这可能会对可能对 Clojure 中的本地库导入感到困惑的未来读者有所帮助。
    【解决方案2】:

    有几种方法可以做到这一点。我不相信你需要一个本地存储库——至少当我上次将 JNI 与 clojure 一起使用时你不需要(但那是在 clojure 1.3 和 lein 从那时起发生了一些变化)。下面的堆栈溢出问题和答案可能会给你一些指示

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

    【讨论】:

    • 谢谢,我对如何将本机依赖项添加到生成的 jar 有了更好的了解。在我的情况下,假定依赖项是在外部安装的,而不是与应用程序捆绑在一起的(jar 只是 JNI 绑定)。真正的问题恰好是我的答案。
    【解决方案3】:

    经过一番调查,我终于找到了答案。问题是我正在使用 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

    【讨论】:

      猜你喜欢
      • 2018-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多