Scala SBT 和 JNI 库

2024-05-09

我正在编写一个简单的应用程序Scala通过以下方式使用 leveldb 数据库leveldbjni图书馆。我的build.sbt文件看起来像这样:

name := "Whatever"

version := "1.0"

scalaVersion := "2.10.2"

libraryDependencies ++= Seq(
    "org.iq80.leveldb" % "leveldb-api" % "0.6",
    "org.fusesource.leveldbjni" % "leveldbjni-all" % "1.7"
)

An Object然后负责创建数据库。不幸的是,如果我运行该程序,我会得到一个java.lang.UnsatisfiedLinkError,由提出hawtjni图书馆那个leveldbjni幕后的利用。

该错误也可以从 scala 控制台轻松触发:

scala> import java.io.File
scala> import org.iq80.leveldb._
scala> import org.fusesource.leveldbjni.JniDBFactory._
scala> factory.open(new File("test"), new Options().createIfMissing(true))

java.lang.UnsatisfiedLinkError: org.fusesource.leveldbjni.internal.NativeOptions.init()V
    at org.fusesource.leveldbjni.internal.NativeOptions.init(Native Method)
    at org.fusesource.leveldbjni.internal.NativeOptions.<clinit>(NativeOptions.java:54)
    at org.fusesource.leveldbjni.JniDBFactory$OptionsResourceHolder.init(JniDBFactory.java:98)
    at org.fusesource.leveldbjni.JniDBFactory.open(JniDBFactory.java:167)
    at .<init>(<console>:15)
...
scala> System getProperty "java.io.tmpdir"
res2: String = /var/folders/1l/wj6yg_wd15sg_gcql001wchm0000gn/T/

我无法理解发生了什么,因为库已从 jar 文件中正确提取,但由于某些原因未加载。

$ file /var/folders/1l/wj6yg_wd15sg_gcql001wchm0000gn/T/lib*
/var/folders/1l/wj6yg_wd15sg_gcql001wchm0000gn/T/libleveldbjni-1.7.jnilib:    Mach-O universal binary with 2 architectures
/var/folders/1l/wj6yg_wd15sg_gcql001wchm0000gn/T/libleveldbjni-1.7.jnilib (for architecture x86_64):    Mach-O 64-bit dynamically linked shared library x86_64
/var/folders/1l/wj6yg_wd15sg_gcql001wchm0000gn/T/libleveldbjni-1.7.jnilib (for architecture i386):  Mach-O dynamically linked shared library i386

我认为这个问题可能与 sbt 使用的类加载器有关,但我不确定,因为我对 scala 比较陌生。

UPDATE

仍然没有找到罪魁祸首是什么或谁。无论如何,库实际上已找到并正确加载,因为我可以执行以下命令:

scalac> import org.fusesource.leveldbjni.internal.NativeDB
scalac> NativeDB.LIBRARY.load()

该错误是由于某种原因init()函数根据hawtjni 文档 http://fusesource.com/forge/sites/hawtjni/documentation/developer-guide.html负责设置所有静态字段都注释为具有常量值的常量字段。仍然可以通过键入以下内容来触发异常:

scalac> import org.fusesource.leveldbjni.internal.NativeOptions
scalac> new NativeOptions()
java.lang.UnsatisfiedLinkError: org.fusesource.leveldbjni.internal.NativeOptions.init()V
    at org.fusesource.leveldbjni.internal.NativeOptions.init(Native Method)
    at org.fusesource.leveldbjni.internal.NativeOptions.<clinit>(NativeOptions.java:54)
    at .<init>(<console>:9)

显然这是一个已知问题,如本文档中所述sbt 问题页面 https://github.com/sbt/sbt/issues/358。我已经实施了,根据事件源文档 https://github.com/eligosource/eventsourced/wiki/Installation#wiki-native, 一个习俗run-nobootcp执行代码而不将 Scala 库添加到启动类路径的命令。

这应该可以解决问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala SBT 和 JNI 库 的相关文章

随机推荐