Scala SBT和JNI库 [英] Scala SBT and JNI library

查看:128
本文介绍了Scala SBT和JNI库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Scala中编写一个简单的应用程序,该应用程序通过leveldbjni库使用leveldb数据库.我的build.sbt文件如下所示:

I am writing a simple app in Scala that uses a leveldb database through the leveldbjni library. My build.sbt file looks like this:

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,由leveldbjni在后台利用的hawtjni库引起.

An Object is then responsible for creating a database. Unfortunately if I run the program I get back a java.lang.UnsatisfiedLinkError, raised by the hawtjni library that leveldbjni exploits under the hood.

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

The error can be triggered easily also from the scala console:

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文件中正确提取,但由于某些原因未加载.

I can't understand what is going on since the library is getting correctly extracted from the jar file but it is not getting loaded for some reasons.

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

I think the problem is probably related to the classloader that sbt employs but I am not sure since I am relatively new to scala.

更新

仍然没有找到肇事者或罪魁祸首.无论如何,实际上可以找到该库并正确加载该库,因为我可以执行以下命令:

Still didn't find what or who is the culprit. Anyway the library is actually found and correctly loaded, since I can execute the following commands:

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

根据hawtjni

The error is somehow due to the init() function that according to the hawtjni documentation is responsible for setting all the static fields annotated as constant fields with the constant value. The exception can still be triggered by typing:

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)

推荐答案

显然,这是此事件源文档,我已经实现了自定义run-nobootcp在不将Scala库添加到启动类路径的情况下执行代码的命令.

Apparently this is a known problem as documented in this sbt issue page. I have implemented, according to the eventsourced documentation, a custom run-nobootcp command that executes the code without adding the Scala library to the boot classpath.

这应该可以解决问题.

这篇关于Scala SBT和JNI库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆