2013-08-16 45 views
8

Tôi đã sử dụng Opencv 2.4.5 với Java trong một thời gian để xây dựng một ứng dụng và bây giờ muốn phân phối ứng dụng. Thư viện được tải bằng cách sử dụng các mục sau:Làm thế nào để đóng gói opencv + java trong một cái bình

static{ 
     System.loadLibrary("opencv_java245"); 
    } 

hoạt động tốt. Tuy nhiên, khi xuất khẩu, nó không hoạt động khi chạy từ jar:

java -jar build1.jar 

File opencv_java245.jar được bao gồm như là một thư viện người dùng, với một tập tin gốc (libopencv_java245.dylib) kết nối với nó. Khi chạy jar thực thi được tạo ra từ Eclipse, tôi nhận được UnsatisfiedLinkError dưới đây, mặc dù mọi thứ biên dịch/chạy tốt trong nhật thực.

Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java245 in java.library.path 
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1860) 
    at java.lang.Runtime.loadLibrary0(Runtime.java:845) 
    at java.lang.System.loadLibrary(System.java:1084) 
    at com.drawbridge.Main.<clinit>(Main.java:12) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:266) 
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:56) 

Bất kỳ ai biết cách đóng gói OpenCV đơn giản trong bình?

Cập nhật: Tôi hiện đã cạn kiệt mọi thứ. Tôi có thể thêm các thư viện để xây dựng đường dẫn của tôi (và không sử dụng System.loadLibrary) và làm việc trong nhật thực, nhưng không phải khi đóng gói trong jar. Tôi đã thử mọi thứ. Tôi cũng đã kiểm tra loại thư viện động mà tôi đang cố gắng tải - đó là

Mach-O 64-bit x86_64 dynamically linked shared library 

có vẻ như nó sẽ hoạt động tốt. Tôi đã sử dụng -D64 và -D32 để kiểm tra và nhận được kết quả tương tự với cả hai.

+1

thể trùng lặp của [Extract và DLL load từ JAR] (http://stackoverflow.com/questions/4764347/extract -and-load-dll-from-jar) –

+2

Bạn không thể tải một thư viện gốc (hoặc DLL) trực tiếp từ một JAR. Xem Câu hỏi được liên kết để biết cách xử lý vấn đề này. –

+0

Cảm ơn @StephenC Tôi đã thử phương pháp này và vẫn nhận được UnsatisfiedLinkError nhưng với một thông điệp khác nhau (một cái gì đó giống như loại không rõ). – alistair

Trả lời

10

Như Steven C đã nói, nó giống như trong Extract and load DLL from JAR và cũng trong một bug report. Tôi đã hơi ngu dốt về cách sử dụng dylibs và đã cố gắng để phù hợp với một OpenCV tutorial mà sử dụng một "thư viện người dùng" để thêm một lọ, và sau đó thêm dylib bản địa. Ngoài ra, vì một số lý do tải tài nguyên ngay cả khi sử dụng "/" được tải từ thư mục src, không phải thư mục gốc của dự án của tôi (đó là trường hợp trong một dự án thử nghiệm tôi đã thực hiện).

Đối với những người cố gắng để làm điều tương tự, đây là một số mã để giúp:

private static void loadLibrary() { 
    try { 
     InputStream in = null; 
     File fileOut = null; 
     String osName = System.getProperty("os.name"); 
     Utils.out.println(Main.class, osName); 
     if(osName.startsWith("Windows")){ 
      int bitness = Integer.parseInt(System.getProperty("sun.arch.data.model")); 
      if(bitness == 32){ 
       Utils.out.println(Main.class, "32 bit detected"); 
       in = Main.class.getResourceAsStream("/opencv/x86/opencv_java245.dll"); 
       fileOut = File.createTempFile("lib", ".dll"); 
      } 
      else if (bitness == 64){ 
       Utils.out.println(Main.class, "64 bit detected"); 
       in = Main.class.getResourceAsStream("/opencv/x64/opencv_java245.dll"); 
       fileOut = File.createTempFile("lib", ".dll"); 
      } 
      else{ 
       Utils.out.println(Main.class, "Unknown bit detected - trying with 32 bit"); 
       in = Main.class.getResourceAsStream("/opencv/x86/opencv_java245.dll"); 
       fileOut = File.createTempFile("lib", ".dll"); 
      } 
     } 
     else if(osName.equals("Mac OS X")){ 
      in = Main.class.getResourceAsStream("/opencv/mac/libopencv_java245.dylib"); 
      fileOut = File.createTempFile("lib", ".dylib"); 
     } 


     OutputStream out = FileUtils.openOutputStream(fileOut); 
     IOUtils.copy(in, out); 
     in.close(); 
     out.close(); 
     System.load(fileOut.toString()); 
    } catch (Exception e) { 
     throw new RuntimeException("Failed to load opencv native library", e); 
    } 
+0

Việc cần làm nếu Hệ điều hành là Linux? –

+0

Có vẻ như Linux sử dụng các tệp .so http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html – alistair