Scala SBT and JNI library

帅比萌擦擦* 提交于 2019-12-10 13:28:26

问题


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

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.

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/

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

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.

UPDATE

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

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)

回答1:


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.

This should solve the problem.



来源:https://stackoverflow.com/questions/17750780/scala-sbt-and-jni-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!