2013-07-19 30 views
6

Tôi đang viết một ứng dụng đơn giản trong Scala sử dụng cơ sở dữ liệu leveldb thông qua thư viện leveldbjni. Tệp build.sbt của tôi trông giống như sau:Thư viện Scala SBT và 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" 
) 

An Object sau đó chịu trách nhiệm tạo cơ sở dữ liệu. Thật không may nếu tôi chạy chương trình, tôi lấy lại một số java.lang.UnsatisfiedLinkError, được nâng lên bởi thư viện hawtjnileveldbjni khai thác dưới mui xe.

Các lỗi có thể được kích hoạt một cách dễ dàng cũng từ 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/ 

Tôi không thể hiểu được những gì đang xảy ra kể từ khi thư viện được việc chiết xuất một cách chính xác từ file jar nhưng không nhận được nạp cho Một số lý do.

$ 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 

Tôi nghĩ rằng vấn đề có thể liên quan đến trình nạp lớp mà sbt sử dụng nhưng tôi không chắc chắn vì tôi tương đối mới với scala.

CẬP NHẬT

Vẫn không tìm thấy những gì hay ai là thủ phạm. Dù sao thư viện được thực sự tìm thấy và đúng nạp, kể từ khi tôi có thể thực hiện các lệnh sau:

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

Lỗi này là bằng cách nào đó do sự init() chức năng mà theo hawtjnidocumentation chịu trách nhiệm cho việc thiết tất cả các trường tĩnh chú thích dưới dạng các trường không đổi với giá trị không đổi. Ngoại lệ vẫn có thể được kích hoạt bằng cách nhập:

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

Nội dung của thuộc tính hệ thống 'java.library.path' là gì? Bạn đã cố gắng đặt thuộc tính này vào đường dẫn nơi các thư viện được trích xuất là? – Beryllium

+0

Có đã thử rằng bằng cách sử dụng tất cả các tùy chọn cấu hình có thể. Vẫn còn lỗi tương tự – nopper

+0

Bạn đang sử dụng phiên bản OS/JDK nào? –

Trả lời

2

Rõ ràng đây là vấn đề đã biết như được ghi trong số sbt issue page này. Tôi đã triển khai, theo eventsourced documentation, lệnh run-nobootcp tùy chỉnh thực thi mã mà không thêm thư viện Scala vào đường dẫn lớp khởi động.

Điều này sẽ giải quyết được sự cố.

+0

Trên OS X 10.8 với sbt 0.13 và scala 2.10 qua MacPorts, tôi nhận được sự cố ban đầu được mô tả. Vấn đề SBT # 358 cho biết vấn đề này nên được sửa với sbt 0.13, nhưng điều đó có vẻ không đúng. Lệnh run-nobootcp tùy chỉnh cũng không hoạt động ... nhưng tôi chỉ sao chép và dán mà không có sự hiểu biết thực sự. Điều thú vị là sử dụng leveldbjni từ bên trong một dự án Play hoạt động tốt. –

+0

Tôi thực sự đang sử dụng scala 2.10 và sbt 0.13 trên OSX 10.8.5 mà không gặp bất kỳ sự cố nào, bằng cách sử dụng tác vụ 'run-nobootcp'. Bạn có chắc chắn rằng bạn đang làm theo hướng dẫn một cách chính xác? – nopper

+0

Tôi không chắc chắn, không, là một Scoo noob. leveldbjni _does_ hoạt động tốt trong ngữ cảnh ứng dụng Play, tuy nhiên, điều đó là đủ tốt trong lúc này. –

Các vấn đề liên quan