2013-07-19 7 views
6

Я пишу простое приложение в Scala, которое использует базу данных leveldb через библиотеку leveldbjni. Мой build.sbt файл выглядит следующим образом:Scala SBT и библиотека JNI

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> 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/ 

Я не могу понять, что происходит, поскольку библиотека становится правильно извлекаются из файла банки, но он не получает загружен для некоторые причины.

$ 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 работает, но я не уверен, так как я относительно новым для Скале.

UPDATE

Все еще не нашли то, что или кто является виновником. Во всяком случае, библиотека фактически найдена и загружена правильно, так как я могу выполнить следующие команды:

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

Ошибка какая-то образом связанно с функцией init(), что в соответствии с hawtjnidocumentation отвечают за установление всех статических полей аннотированных как постоянные поля с постоянным значением. Исключение может еще быть вызвано типизации:

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) 
+0

Что такое системное свойство 'java.library.path'? Вы пытались установить это свойство на путь, где находятся извлеченные библиотеки? – Beryllium

+0

Да, уже пробовал это, используя все возможные варианты конфигурации. По-прежнему такая же ошибка – nopper

+0

Какие версии ОС/JDK вы используете? –

ответ

2

Видимо, это известная проблема, как описано в этом sbt issue page. Я выполнил, согласно eventsourced documentation, пользовательскую команду run-nobootcp, которая выполняет код без добавления библиотеки Scala в путь к загрузке.

Это должно решить проблему.

+0

В OS X 10.8 с sbt 0.13 и scala 2.10 через MacPorts я впервые получил описанную проблему. SBT Issue # 358 указывает, что эта проблема должна быть исправлена ​​с помощью sbt 0.13, но это, похоже, не так. Пользовательская команда run-nobootcp также не работает ... но я просто копирую и вставляю без реального понимания. Интересно, что использование leveldbjni из Play-проекта отлично работает. –

+0

Я фактически использую scala 2.10 и sbt 0.13 на OSX 10.8.5 без каких-либо проблем, используя задачу 'run-nobootcp'. Вы уверены, что правильно следуете инструкциям? – nopper

+0

Я совсем не уверен, нет, будучи Scala noob. leveldbjni _does_ отлично работает в контексте приложения Play, хотя это пока достаточно хорошо. –

Смежные вопросы