Scala SBT 和 JNI 库

标签 scala java-native-interface sbt leveldb

我正在写一个简单的应用程序 Scala通过 leveldbjni 使用 leveldb 数据库图书馆。我的 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"
)

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 比较陌生。

更新

仍然没有找到什么或谁是罪魁祸首。无论如何,实际上找到并正确加载了库,因为我可以执行以下命令:
scalac> import org.fusesource.leveldbjni.internal.NativeDB
scalac> NativeDB.LIBRARY.load()

该错误不知何故是由于 init()函数,根据 hawtjni documentation负责设置所有注释为具有常量值的常量字段的静态字段。仍然可以通过键入以下内容来触发异常:
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 issue page 中。 .我已经实现了,根据eventsourced documentation , 自定义 run-nobootcp执行代码而不将 Scala 库添加到引导类路径的命令。

这应该可以解决问题。

关于Scala SBT 和 JNI 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17750780/

相关文章:

scala - sequenceU 返回 G.M[List[G.A]] 而不是预期类型

java - OpenCV 2.4.1 : UnsatisfiedLinkError

scala - 并行运行 ScalaTest 测试

gradle 2.6 Play 插件 : How to add play local dependency

scala - 在常量表达式中使用 scala 常量

scala - Akka HTTP Websocket,如何识别actor内部的连接

引用成员类型的 Scala 宏

java - nar-maven-plugin 和 native-library-loader 不加载 native 库

android - JNI GetMethodId 返回空

java - 如何使用 sbt 和 Java 1.8 生成能够在 Java 1.7 上运行的 jar 文件