2016-04-21 207 views
5

從Eclipse執行時,代碼工作正常。我正在使用OpenCV 2.4.11和JavaFX進行用戶界面。當我從Eclipse導出一個可執行的JAR和CMD我得到下面的異常運行:導出的(Eclipse)可執行文件jar文件中的UnsatisfiedLinkError

enter image description here

我跟很多張貼在這裏的SO和OpenCV論壇(1234),但是,沒有的答案似乎幫助我。

我已經將OpenCV jar添加爲庫,並且本機庫鏈接到/ build/java/x64,如SO答案中的建議。

Java Build path

唯一的例外發生在的System.loadLibrary(Core.Native_Library_Name),我檢查了Native_Library_Name和OpenCV的版本是一樣的一個我在我的項目進口。

public class CustomFrame extends Application{ 

    @Override 
    public void start(Stage primaryStage){ 
     Group root = new Group(); 
     Canvas canvas = new Canvas(1440, 840); 

     ImageView imageView = new ImageView(); 
     imageView.setFitHeight(canvas.getHeight()); 
     imageView.setFitWidth(canvas.getWidth()); 
     new FrameController().startCamera(imageView); 

     root.getChildren().addAll(imageView, canvas); 
     primaryStage.setScene(new Scene(root)); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) 
    { 
     // load the native OpenCV library 
     System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 
     launch(args); 
    } 
} 

如果有人認爲我錯過了什麼,請讓我知道。

+0

既然你似乎已經找到了你的解決方案,我建議你還是先看看我的。與我一樣,您不必像在其他解決方案中那樣指定任何絕對路徑,一旦您將應用程序交給另一個用戶或安裝不同版本的OpenCV,這顯然會中斷您的調用。 – Roland

回答

4

UnsatisfiedLinkError當應用程序試圖加載本地庫像

  1. 在Linux中.so被拋出,
  2. .dll在Windows或
  3. .dylib在Mac

該庫不存在

具體而言,爲了查找所需的本機庫,JVM同時在PATH environment variablejava.library.path系統屬性中查找。

有時,如果本機庫已經由應用程序 和相同的應用程序加載嘗試再次加載它,這也導致此 錯誤。


How to deal with the UnsatisfiedLinkError?

是,我們必須驗證在System.loadLibrary方法傳遞的參數是正確的,該庫確實存在,並首次。請注意,庫的擴展名不是必需的。因此,如果您的庫名爲SampleLibrary.dll,則必須將SampleLibrary值作爲參數傳遞。

此外,如果庫已被應用程序加載,並且應用程序試圖再次加載它,則JVM將引發UnsatisfiedLinkError。另外,您必須確認本地庫存在於應用程序的java.library.pathPATH environment library中。 如果仍然無法找到該庫,請嘗試提供System.loadLibrary方法的絕對路徑。

爲了執行您的應用程序,請使用-Djava.library.path參數來顯式指定本機庫。例如,使用終端(Linux或Mac)或命令提示符(Windows)中,通過發出以下命令來執行你的應用程序:

java -Djava.library.path= "<path_of_your_application>" –jar <ApplicationJAR.jar> 

你已經錯過了實際的命令。使用以下

java -Djava.library.path="C:\Opencv2.1.11\opencv\build\java\x64" -jar BlurDetector.jar 

java -Djava.library.path="C:\Opencv2.1.11\opencv\build\java" -jar BlurDetector.jar 

,而不是你的命令

java -Djava.library.path="C:\Users\vivek_elango\Desktop" -jar BlurDetector.jar // you have given wrong path of your application 
2

看起來您需要將包含opencv-2411本機庫的路徑添加到從命令提示符運行時的-Djava.library.path

因此,像這樣:

java -Djava.library.path="C:\Opencv2.1.11\opencv\build\java\x64" -jar BlurDetector.jar 
1

在對面的其他答案,我寧願建議你永遠不會使用絕對路徑,而不是使用相對的。當您將軟件交給另一個用戶時,用戶肯定不會將庫與您在同一路徑上。通過對應用程序使用相對路徑,您可以保證軟件也可以在其他用戶系統上運行,而無需設置路徑變量,jvm指令以及不需要的路徑變量。他們甚至不需要安裝OpenCV,如果你以這種方式給他們的圖書館的DLL。

這裏的代碼加載庫以相對方式:

public static void initOpenCv() { 

    setLibraryPath(); 

    System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 

    System.out.println("OpenCV loaded. Version: " + Core.VERSION); 

} 

private static void setLibraryPath() { 

    try { 

     System.setProperty("java.library.path", "lib/x64"); 

     Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); 
     fieldSysPath.setAccessible(true); 
     fieldSysPath.set(null, null); 

    } catch (Exception ex) { 
     ex.printStackTrace(); 
     throw new RuntimeException(ex); 
    } 

} 

所有您需要做的是

  • 把圖書館變成的lib/x64文件夾相對於你的jar文件
  • 在您的應用程序中,您必須在程序開始時調用initOpenCv()

就是這樣。這樣您可以像以前一樣開發並維護可分發的應用程序。


以下是完整版本:

import java.lang.reflect.Field; 

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.control.Label; 
import javafx.scene.layout.HBox; 
import javafx.stage.Stage; 

import org.opencv.core.Core; 

public class Main extends Application { 

    @Override 
    public void start(Stage primaryStage) { 

     initOpenCv(); 

     HBox root = new HBox(); 

     Label infoLabel = new Label(); 
     infoLabel.setText("OpenCV loaded. Version: " + Core.VERSION); 

     root.getChildren().add(infoLabel); 

     Scene scene = new Scene(root, 400, 400); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public static void initOpenCv() { 

     setLibraryPath(); 

     System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 

     System.out.println("OpenCV loaded. Version: " + Core.VERSION); 

    } 

    private static void setLibraryPath() { 

     try { 

      System.setProperty("java.library.path", "lib/x64"); 

      Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); 
      fieldSysPath.setAccessible(true); 
      fieldSysPath.set(null, null); 

     } catch (Exception ex) { 
      ex.printStackTrace(); 
      throw new RuntimeException(ex); 
     } 

    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

有了這樣的文件夾結構:

.\application.jar 
.\lib\x64\*.dll 

提示:我打包OpenCV的水罐裏的應用程序。罐子

相關問題