2009-04-17 38 views
7

Tôi có một thư viện gọi HelloWorld.so và HelloWorld.java chương trình với nội dung này:Tại sao tôi nhận được UnsatisfiedLinkError này với mã gốc?

class HelloWorld { 
    private native void print(); 
    public static void main(String[] args) { 
     new HelloWorld().print(); 
    } 
    static { 
     System.loadLibrary("HelloWorld"); 
    } 
} 

Bây giờ khi tôi cố gắng chạy HelloWorld.java tôi nhận được lỗi này:

 
$ /usr/java1.4/bin/java HelloWorld 
Exception in thread "main" 
java.lang.UnsatisfiedLinkError: no HelloWorld in java.library.path 
     at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1491) 
     at java.lang.Runtime.loadLibrary0(Runtime.java:788) 
     at java.lang.System.loadLibrary(System.java:834) 
     at HelloWorld.<clinit>(HelloWorld.java:7) 

Bất cứ lời khuyên ?

+0

Nếu bạn sử dụng Linux (Ubuntu terminal), Sau đó, hãy có một cái nhìn vào http://saurabhsharma123k.blogspot.in/2017 /07/java-jni-and-cc-from-command-line.html –

Trả lời

0

@mmyers Cảm ơn bạn đã phản hồi. Chúng tôi phát hiện ra rằng tất cả những gì chúng tôi phải làm là thay đổi System.loadLibrary thành System.load và chuyển toàn bộ đường dẫn + tên tệp làm đối số, làm việc như một sự quyến rũ.

Thậm chí trước khi làm như vậy, chúng tôi đã thử sử dụng tham số "-D" và đặt LD_LIBRARY_PATH nhưng chúng tôi đã không thành công.

Tìm hình! :)

Cảm ơn một lần nữa, Karen

+0

Điều đó quá lạ. loadLibrary nên hoạt động giống hệt nhau, ngoại trừ việc nó yêu cầu thư viện phải nằm trên đường dẫn. Đó là những gì -Djava.libary.path là nghĩa vụ phải giúp đỡ. –

+0

Tôi không biết điều đó .... Tôi rất thích nó nếu một ngày nào đó ai đó có thể giải thích :) – KNewton

+1

Đã không làm việc cho tôi! –

7

HelloWorld.so nằm ở đâu? Bạn có thể cần phải xác định thư mục cha của nó bằng cách sử dụng tham số dòng lệnh "-Djava.library.path". Ví dụ: nếu là số "/path/libs/HelloWorld.so", hãy thêm -Djava.library.path=/path/libs làm tùy chọn khi gọi java. Ví dụ: số "-Djava.library.path=lib" trên một trong các dự án của tôi.

Chỉnh sửa: Dan Dyer chỉ ra rằng biến môi trường LD_LIBRARY_PATH cũng có thể được sử dụng cho việc này.

+0

Phần mở rộng .so có cần phải được khai báo rõ ràng không? – Otis

+0

Chỉnh sửa để làm rõ (nó thực sự là đường dẫn đến thư mục chứa tệp .so). –

+0

@erickson: Cảm ơn, điều đó có vẻ tốt hơn. –

8

Tôi có vấn đề này và cố định nó bằng cách đổi tên thư viện của tôi để libHelloWorld.so và sau đề nghị Michael Myers. Tôi đang sử dụng Arch Linux 64 bit.

HelloWorld.c:

#include <jni.h> 
#include <stdio.h> 
#include "HelloWorld.h" 

/* shamelessly stolen from the book 'The Java Native Interface: Programmer's 
    Guide and Specification' */ 
JNIEXPORT void JNICALL 
Java_HelloWorld_print (JNIEnv *env, jobject obj) { 
    printf("Hello World!\n"); 
} 

HelloWorld.java:

class HelloWorld { 
    private native void print(); 
    public static void main(String[] args) { 
     new HelloWorld().print(); 
    } 
    static { 
     System.loadLibrary("HelloWorld"); 
    } 
} 

Xây dựng và thử nghiệm:

$ javac HelloWorld.java 
$ javah -classpath . HelloWorld 
$ gcc -shared -fPIC -I $JAVA_HOME/include -I $JAVA_HOME/include/linux HelloWorld.c -o libHelloWorld.so 
$ java -classpath . -Djava.library.path=. HelloWorld 
Hello World! 

tl; dr: đặt lib vào đầu tên tập tin của thư viện

+1

tl; dr vừa lưu ngày của tôi – serj

11

Tôi nghĩ rằng một số điểm rất hữu ích khi nhận được lỗi này:

  1. Kiểm tra tính nhất quán của tên hàm trong file .c và tạo file ( .h)
  2. Tên của thư viện JNI dựa trên hệ điều hành. Ví dụ: Trong HelloWorld.java, System.loadLibrary("HelloWorld");
    • Solaris: libHelloWorld.so
    • Linux: libHelloWorld.so
    • Win: HelloWorld.dll
    • Mac: libHelloWorld.jnilib
  3. Khi chạy, thêm -Djava.library.path=PATH. PATH để đặt nơi bạn đặt thư viện JNI bạn

Đây là tài liệu tham khảo của tôi: https://blogs.oracle.com/moonocean/entry/a_simple_example_of_jni

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