10

在 64 位 JVM 上,在 Linux 中,无论本地库加载如何,都坚持尝试加载 32 位库。

我问这是一个clojure和(甚至更多)java n00b。

到目前为止我找到的答案(在 Leiningen/Clojure 中使用 lwjgl似乎是搜索结果中最突出的)似乎适用于旧版本的 lein,问题围绕 project.clj 中的 :native-dependencies 或 LD_LIBRARY_PATH 旋转。

我正在重新发明轮子并将基本的 jME 教程翻译成 clojure,作为学习它们的一些个人家庭作业。在迄今为止我发现的所有教程和示例中,人们展示了他们是如何做到这一点的,这部分似乎“正常工作”。

(就此而言,它在 Windows 下对我来说工作得很好)。

我正在使用 lein 构建一个新的空项目。我已经在 clojars 上设置了对各种版本的 jMonkeyEngine 库的依赖。在 'lein deps' 之后,liblwjgl64.so 和 libopenal64.so 在我的项目目录的根目录中结束。

当我尝试“lein run”时,它会显示设置的猴子启动画面,然后在尝试实际运行时抛出异常,因为它正在尝试加载 liblwjgl.so。

该文件位于 target/native/linux 和 target/native/linux64 下(但奇怪的是,不在 target/native/linux32 下)。

如果我将它想要的文件复制到我的项目的根目录中,错误将变为“错误的 ELF 类:ELFCLASS32(可能的原因:架构字宽不匹配)”,这是谷歌不断给我的另一组讨论。那里提到的解决方案似乎都相当于“切换到 32 位 JVM 以使 Minecraft 正常工作”,但我更愿意了解正在发生的事情的实际线索。

这个问题在我可以在 clojars 中使用的每一组依赖库中都非常一致(无论如何,回到第 2 版……那些似乎不值得深入研究的更大问题)。查尔斯染色在窗户上为我设置了“刚刚工作”。

到目前为止,我能够提出的最好的假设是这样的:

我怀疑必须在某个时候指定一个版本。http://docs.oracle.com/javase/7/docs/technotes/guides/javaws/developersguide/syntax.html#resources提到了一个看起来非常合适的资源属性,但这似乎没有任何意义用 JNLP 做。我想知道是否有一个清单文件位于我无法找到的 .jar 中的某个地方(这就是我的 n00bishness 发挥作用的地方......我真的不知道我在寻找什么)。

那么,是否有人对我应该看哪里或应该问谁有任何指示?我什至不知道从这里去哪里。纠缠 jMonkeyEngine 论坛、#clojure 或 lwjgl 邮件列表(或他们使用的任何东西......我实际上根本没有调查过他们的事情......我应该吗?)

我要尝试的下一件事是将 jME 库捆绑到我自己的存储库中。这似乎是一项艰巨而艰巨的任务,我决定在处理这个问题时在这里提出。

我知道这很模糊,我为此道歉。我的 google-fu 让我失望了。我会很感激任何人能提出的任何建议。

提前致谢!

4

3 回答 3

1

我知道这是一个老问题,但我在决定从事 Clojure + jMonkeyEngine 项目时发现了它。我花了一些时间与 clojars 中的包进行斗争,然后研究构建我自己的 maven 包需要什么,我在 jMonkeyEngine wiki 上找到了一个页面,上面有这个严厉的警告:

请注意,核心 jME 团队既不推荐也不支持将 jME3 与 maven 一起使用,并且 maven 存储库中的库可能已过时!

后来我发现我能够成功地运行一个最小的 JME 应用程序,方法是将它们的 jar 直接放在我的项目中,并使用 leiningen 的 :resource-paths 配置将它们包含在类路径中。

通过下载 JME3 SDK 并在 jmonkeyplatform/jmonkeyplatform/libs 中查找 jars。将所有 jar 复制到项目内的“lib”文件夹中(是的,您可以删除不会使用的 jar)。然后像这样配置你的 lein 项目:

(defproject my-jme-project "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.5.1"]]
  :resource-paths ["resources" "lib/*"])

运行 lein-repl,下面应该会启动一个最小的 JME3 应用程序:

(import 'com.jme3.app.SimpleApplication)
(def app (proxy [SimpleApplication] [] (simpleInitApp [] nil)))
(.start app)
于 2013-11-14T01:48:53.597 回答
0

在 Java 程序中使用本机库一开始可能会很痛苦,但实际上并没有那么复杂。

首先,你的错误,wrong ELF class: ELFCLASS32意味着某些64-bit 程序试图加载32-bit shared library。显然,当程序查找库的路径上存在具有所需名称的 32 位库,但程序本身是 64 位时,就会发生这种情况。这几乎就是对错误的解释。

现在,关于问题的主要部分。确实有几种方法可以在 Java 应用程序中使用本机库,其中一些甚至涉及环境变量。但 IMO 最简单的方法是指定 Java系统属性 java.library.path,这正是用于管理本机库的。此属性应指向程序的所有本机库所在的目录。JVM 将在该目录中查找所有必需的共享对象。

直接运行 JAR 文件时,可以在命令行中指定系统属性,如下所示:

java -Djava.library.path=natives/linux64 -jar yourprogram.jar

在这里,我们指定了相对于当前目录的库路径。就我而言,这是为通常由脚本启动的独立应用程序设置属性的首选方式。

至于 REPL,似乎可以在里面为其设置 JVM 选项project.clj,如下所示:

(defproject project "version"
  ...
  :jvm-opts ["-Djava.library.path=target/natives/linux64"])

我不记得 REPL 的默认工作目录是什么,所以这可能需要对确切的路径进行一些试验,但你明白了。

现在我正在自己开发 lwjgl 程序(虽然不是在 Clojure 中,而是在纯 Java 中,使用 Maven),真正需要的是从 jar 中提取本机库(maven-native-plugin这样做)并java.library.path为它们设置。

顺便说一句,看起来 leiningen 支持 , 中的另一个重要选项project.clj:native-path这似乎启用了类似maven-native-plugin功能:它指定了一个目录,所有本机依赖项都应提取到该目录。将其与:jvm-opts应该为您提供正确的独立于平台的 REPL :)

于 2013-02-05T05:18:18.600 回答
0

仍然是老问题,但我遇到了同样的问题,所以我可以通过在文件中添加 jCenter 存储库来在 Closure 上设置 jME3 project.clj

(defproject example-project "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :repositories [["jcenter" "http://jcenter.bintray.com"]]
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [org.jmonkeyengine/jme3-core "3.1.0-beta1"]
                 [org.jmonkeyengine/jme3-desktop "3.1.0-beta1"]
                 [org.jmonkeyengine/jme3-lwjgl "3.1.0-beta1"]])
于 2016-10-12T15:16:59.900 回答