2013-07-19 6 views
6

私はScalaに、leveldbjniライブラリを介してleveldbデータベースを使用する単純なアプリケーションを書いています。私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のコンソールからも簡単にトリガすることができます。

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が採用しているクラスローダーに関係していると思いますが、私は比較的新しいスケーラであるため、わかりません。

UPDATE

はまだ何か誰が犯人であるが見つかりませんでした。私は、次のコマンドを実行することができますので、とにかくライブラリーは、実際に発見され、正しくロードされます。

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

エラーが原因hawtjnidocumentationに応じて注釈を付けすべての静的フィールドを設定するための責任があるinit()関数に何とかです定数値の定数フィールドとして指定します。

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

どのOS/JDKバージョンを使用していますか? –

答えて

2

をこのsbt issue pageに記載されているようどうやらこれは既知の問題です:例外は、まだ入力することによってトリガすることができます。私はeventsourced documentationに従って、カスタムクラスrun-nobootcpを実装しました。コマンドは、Scalaライブラリをブートクラスパスに追加せずにコードを実行します。

これは問題を解決するはずです。

+0

MacPorts経由のsbt 0.13とscala 2.10のOS X 10.8では、最初に説明した問題が発生します。 SBT Issue#358は、この問題をsbt 0.13で修正する必要があることを示していますが、そうではないようです。カスタムrun-nobootcpコマンドも動作しません...しかし、私は実際の理解なしにコピーして貼り付けています。興味深いことに、Playプロジェクト内のleveldbjniを使用すると効果的です。 –

+0

'run-nobootcp'タスクを使うことで、実際には問題なく、OSX 10.8.5上でscala 2.10とsbt 0.13を実際に使用しています。指示に正しく従っていることを確認してください。 – nopper

+0

私はまったく確信していません。いいえ、Scala noobです。しかし、leveldbjni _does_は、再生アプリのコンテキスト内でうまく動作しますので、当分の間は十分です。 –

関連する問題