Clojure和64位lwjgl(lein 2)

10
在Linux上的64位JVM中,无论什么东西加载本地库都坚持尝试加载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工作”,但我更想了解到底发生了什么。
这个问题在我手头上可以获得的每一组依赖库中都非常一致(至少返回到版本2...那些有更大的问题,似乎不值得深入挖掘)。Charles-stain集合在Windows上对我来说“只是工作”。
到目前为止,我能想到的最好的假设是这样的:
我怀疑必须在某个时候指定版本。http://docs.oracle.com/javase/7/docs/technotes/guides/javaws/developersguide/syntax.html#resources提到了一个看起来很合适的资源属性,但这似乎与JNLP无关。我想知道是否有一个清单文件坐落在.jar中,我找不到它(这就是我的新手问题...我不知道我在找什么)。那么,有没有人能给我一些提示,告诉我该去哪里或者问谁?我甚至不知道下一步该做什么。更明智的做法是骚扰jMonkeyEngine论坛、#clojure或者lwjgl邮件列表(或者他们使用的任何东西...我实际上还没有研究过他们的方面...我应该吗?)接下来我要尝试的是将jME库打包到我的自己的存储库中。这似乎是一项庞大而艰巨的任务,所以在我处理这个问题时,我决定在这里问问。
我知道这个问题比较模糊,对此我感到抱歉。我的谷歌搜索能力已经失败了。如果有人能提出任何建议,我将不胜感激。
提前感谢!
3个回答

1
我知道这是一个老问题,但我在决定开发Clojure + jMonkeyEngine项目时找到了它。我花了一些时间在clojars的软件包上奋斗,然后研究了构建自己的maven软件包需要什么,最后我在jMonkeyEngine维基上找到了这个严厉的警告:
请注意,使用maven与jME3既不被核心jME团队推荐也不得到支持,并且maven存储库中的库可能已过时!
后来我发现,通过将它们的jar文件直接放入我的项目中,并使用leiningen的:resource-paths配置将它们包含在类路径中,我能够成功地运行一个最小的JME应用程序。
下载JME3 SDK并查看jmonkeyplatform/jmonkeyplatform/libs,找到这些jar文件。将所有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)

0

虽然这是一个老问题,但我遇到了同样的问题,所以我能够通过在project.clj文件中添加jCenter存储库来设置jME3:

(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"]])

0

使用Java程序与本地库可能会一开始有些麻烦,但实际上并不是非常复杂。

首先,你的错误信息wrong ELF class: ELFCLASS32意味着某个64位程序试图加载32位共享库。显然,当路径中存在所需名称的32位库,但程序本身是64位时,就会发生这种情况。这基本上就是对错误的解释。

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

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

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

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

至于REPL,似乎可以在project.clj中设置JVM选项,像这样:

(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 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接