簡體   English   中英

java.lang.UnsatisfiedLinkError 在 java.library.path 中沒有 *****.dll

[英]java.lang.UnsatisfiedLinkError no *****.dll in java.library.path

如何在我的 Web 應用程序中加載自定義 dll 文件? 我嘗試了以下方法:

  • 復制system32文件夾中所有必需的 dll 並嘗試在Servlet構造函數System.loadLibrary加載其中之一
  • 將所需的 dll 復制到tomcat_home/shared/libtomcat_home/common/lib

所有這些 dll 都在 web 應用程序的WEB-INF/lib

為了使System.loadLibrary()工作,庫(在 Windows 上,DLL)必須位於PATHjava.library.path系統屬性中列出的路徑中的某個目錄中(因此您可以像java -Djava.library.path=/path/to/dir )。

此外,對於loadLibrary() ,您指定庫的基本名稱,末尾不帶.dll 因此,對於/path/to/something.dll ,您只需使用System.loadLibrary("something")

您還需要查看您得到的確切UnsatisfiedLinkError 如果它說的是:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path

那么它在您的PATHjava.library.path找不到foo庫(foo.dll)。 如果它說的是:

Exception in thread "main" java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()V

那么庫本身就有問題,因為 Java 無法將應用程序中的原生 Java 函數映射到其實際的原生對應物。

首先,我會在您的System.loadLibrary()調用周圍放置一些日志,以查看它是否正確執行。 如果它拋出異常或者不在實際執行的代碼路徑中,那么你總是會得到上面解釋的后一種類型的UnsatisfiedLinkError

作為旁注,大多數人將他們的loadLibrary()調用放入具有本機方法的類中的靜態初始化塊中,以確保它始終只執行一次:

class Foo {

    static {
        System.loadLibrary('foo');
    }

    public Foo() {
    }

}

在運行時更改 'java.library.path' 變量是不夠的,因為它只被 JVM 讀取一次。 你必須像這樣重置它:

System.setProperty("java.library.path", path);
//set sys_paths to null
final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
sysPathsField.setAccessible(true);
sysPathsField.set(null, null);

請查看: 在運行時更改 Java 庫路徑

Adam Batkin 的原始答案將引導您找到解決方案,但是如果您重新部署您的 web 應用程序(不重新啟動您的 web 容器),您應該遇到以下錯誤:

java.lang.UnsatisfiedLinkError: Native Library "foo" already loaded in another classloader
   at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1715)
   at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1646)
   at java.lang.Runtime.load0(Runtime.java:787)
   at java.lang.System.load(System.java:1022)

發生這種情況是因為最初加載您的 DLL 的 ClassLoader 仍然引用此 DLL。 但是,您的 web 應用程序現在正在使用新的 ClassLoader 運行,並且由於正在運行相同的 JVM,並且 JVM 不允許對同一個 DLL 進行 2 次引用,因此您無法重新加載它。 因此,您的 web 應用程序無法訪問現有的 DLL,也無法加載新的 DLL。 所以......你被卡住了。

Tomcat 的 ClassLoader 文檔概述了為什么重新加載的 web 應用程序在新的隔離 ClassLoader 中運行以及如何解決此限制(在非常高的級別)。

解決方案是稍微擴展 Adam Batkin 的解決方案:

   package awesome;

   public class Foo {

        static {
            System.loadLibrary('foo');
        }

        // required to work with JDK 6 and JDK 7
        public static void main(String[] args) {
        }

    }

然后將一個只包含這個編譯類的 jar 放入 TOMCAT_HOME/lib 文件夾中。

現在,在你的 webapp 中,你只需要強制 Tomcat 引用這個類,這可以像這樣簡單地完成:

  Class.forName("awesome.Foo");

現在您的 DLL 應該被加載到公共類加載器中,並且即使在重新部署之后也可以從您的 web 應用程序中引用。

合理?

可以在 google 代碼static-dll-bootstrapper上找到工作參考副本。

您可以使用System.load()提供您想要的絕對路徑,而不是相應操作系統的標准庫文件夾中的文件。

如果您想要已經存在的本機應用程序,請使用System.loadLibrary(String filename) 如果你想提供你自己的,你可能會更好地使用 load()。

您還應該能夠在正確設置java.library.path使用loadLibrary 有關顯示正在檢查的兩個路徑的實現源,請參閱ClassLoader.java (OpenJDK)

在問題是 System.loadLibrary 找不到相關 DLL 的情況下,一個常見的誤解(由 Java 的錯誤消息強化)是系統屬性 java.library.path 是答案。 如果您將系統屬性 java.library.path 設置為您的 DLL 所在的目錄,那么 System.loadLibrary 確實會找到您的 DLL。 但是,如果您的 DLL 又依賴於其他 DLL(通常是這種情況),那么 java.library.path 將無濟於事,因為依賴 DLL 的加載完全由操作系統管理,而操作系統對 java.library 一無所知。小路。 因此,在啟動 JVM 之前繞過 java.library.path 並簡單地將 DLL 的目錄添加到 LD_LIBRARY_PATH (Linux)、DYLD_LIBRARY_PATH (MacOS) 或 Path (Windows) 幾乎總是更好。

(注意:我在 DLL 或共享庫的一般意義上使用術語“DLL”。)

如果您需要加載一個與您所在目錄相關的文件(例如在當前目錄中),這里有一個簡單的解決方案:

File f;

if (System.getProperty("sun.arch.data.model").equals("32")) {
    // 32-bit JVM
    f = new File("mylibfile32.so");
} else {
    // 64-bit JVM
    f = new File("mylibfile64.so");
}
System.load(f.getAbsolutePath());

對於那些正在尋找java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path

我面臨着同樣的例外; 我嘗試了一切,使其工作的重要事情是:

  1. pdf lib.jar 的正確版本(在我的情況下,它是服務器運行時中保存的錯誤版本 jar)
  2. 創建一個文件夾並將 pdflib jar 保存在其中,並將該文件夾添加到您的 PATH 變量中

它適用於 tomcat 6。

  1. 如果您認為您將本機 lib 的路徑添加到%PATH% ,請嘗試使用以下方法進行測試:

     System.out.println(System.getProperty("java.library.path"))

它應該告訴你你的 dll 是否在%PATH%

  1. 重新啟動 IDE Idea,在我通過將 env 變量添加到%PATH%來設置環境變量后,它似乎對我有用

可憐的我 ! 在這后面花了一整天。如果有任何機構復制了這個問題,就把它寫在這里。

我試圖按照 Adam 的建議進行加載,但隨后遇到了 AMD64 vs IA 32 異常。您的 JRE 和 JDK 是 64 位,並且您已將其正確添加到類路徑中。

我的工作示例在這里:未統計的鏈接錯誤

對於 Windows,我發現當我將填充物(jd2xsx.dll 調用和 ftd2xx.dll)加載到 windowws/system32 文件夾時,這解決了問題。 然后我遇到了我的新 fd2xx.dll 與參數有關的問題,這就是為什么我必須加載這個 dll 的舊版本。 稍后我將不得不解決這個問題。

注意:jd2xsx.dll 調用 ftd2xx.dll,所以只設置 jd2xx.dll 的路徑可能不起作用。

我正在使用 Mac OS X Yosemite 和 Netbeans 8.02,我遇到了同樣的錯誤,我找到的簡單解決方案與上面類似,當您需要在項目中包含本機庫時,這很有用。 為 Netbeans 做下一個:

1.- Right click on the Project
2.- Properties
3.- Click on RUN
4.- VM Options: java -Djava.library.path="your_path"
5.- for example in my case: java -Djava.library.path=</Users/Lexynux/NetBeansProjects/NAO/libs>
6.- Ok

我希望它對某人有用。 我找到解決方案的鏈接在這里: java.library.path – What is it and how to use

我遇到了同樣的問題,錯誤是由於 dll 的重命名。 可能會發生庫名稱也寫在 dll 內的某處。 當我放回它的原始名稱時,我能夠使用System.loadLibrary加載

很簡單,只需在 Windows 的命令行上寫入 java -XshowSettings:properties,然后將所有文件粘貼到 java.library.path 顯示的路徑中。

首先,您需要確保本機庫的目錄位於java.library.path 在這里查看如何做到這一點 然后,您可以調用System.loadLibrary(nativeLibraryNameWithoutExtension) - 確保庫名稱中不包含文件擴展名。

This is My java.library.path:

 java.library.path = C:\Program Files\Java\jdk1.7.0_51\bin
     C:\WINDOWS\Sun\Java\bin
     C:\WINDOWS\system32
     C:\WINDOWS
     C:\WINDOWS\system32
     C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\lib\idrskr
.lib
     C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSG
idgeDll.dll
     C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSG
aderDll.dll
     C:\Program Files\Java\jdk1.7.0_51\bin
     C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include
     C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\lib
     C:\WINDOWS\System32\Wbem
     C:\WINDOWS\System32\WindowsPowerShell\v1.0
     C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\
     C:\Program Files\Microsoft SQL Server\100\DTS\Binn

Still rror comes: 
infile >> D:\pdf_upload\pre_idrs15_win_temporary_license_activation_tutorial.pdf
outFile >> D:\pdf_upload\processed\pre_idrs15_win_temporary_license_activation_tutorial.txt
Hello : This is java library path:(NICKRJ) C:\Program Files\Java\jdk1.7.0_51\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:/Program Files/Java/jdk1.7.0_51/jre/bin/server;C:/Program Files/Java/jdk1.7.0_51/jre/bin;C:/Program Files/Java/jdk1.7.0_51/jre/lib/amd64;C:\WINDOWS\system32;C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\lib\idrskrn15.lib;C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSGEBridgeDll.dll;C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSGEReaderDll.dll;C:\Program Files\Java\jdk1.7.0_51\bin;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\lib;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0;C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\DTS\Binn;D:\WorkSet\New folder\eclipse_kepler\eclipse;;.
Exception in thread "main" java.lang.UnsatisfiedLinkError: no iDRMSGEBridgeDll in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1886)
    at java.lang.Runtime.loadLibrary0(Runtime.java:849)
    at java.lang.System.loadLibrary(System.java:1088)
    at com.bi.iDRMSGEBridgeDll.callOcr(iDRMSGEBridgeDll.java:78)
    at com.bi.iDRMSGEBridgeDll.main(iDRMSGEBridgeDll.java:15)


Here is my Java JNI class:

package com.bi;

import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;

public class iDRMSGEBridgeDll  
{
  public native int iDRMSGEDll_Initialize(String strPropertiesFileName);
  public native int iDRMSGEDll_VerifyLicense();
  public native int iDRMSGEDll_ConvertFile(String strSourceFileName, String srcOutputFileName,  String formatType);
  public native int iDRMSGEDll_Finalize();

public static void main(String[] args)
{
    //iDRMSGEBridgeDll.callOcr("bgimage.jpg","jpg","","d:\\","d:\\","4");
    iDRMSGEBridgeDll.callOcr("pre_idrs15_win_temporary_license_activation_tutorial.pdf","pdf","","D:\\pdf_upload","D:\\pdf_upload\\processed","4");


    /*  System.loadLibrary("iDRMSGEBridgeDll");
        iDRMSGEBridgeDll obj = new iDRMSGEBridgeDll();
        if ( obj.iDRMSGEDll_Initialize("D:\\iris\\iDRSGEDll.properties") != 0 ) {
            obj.iDRMSGEDll_Finalize();
            return;
        }
        System.out.println("iDRMSGEDll_Initialize success.");
        if ( obj.iDRMSGEDll_VerifyLicense() != 0 ) {
            obj.iDRMSGEDll_Finalize();
            return;
        }
        System.out.println("iDRMSGEDll_VerifyLicense success.");
        if (obj.iDRMSGEDll_ConvertFile("E:\\UI changes File_by Shakti\\PDF\\S14-005_FRAMEWORK_AGREEMENT_FOR_ENGINE_MAINTENANCE_SERVICES_EASYJET[1].pdf", 
            "E:\\SK_Converted_Files\\MVP_CONTRACTS\\Southwest CFM56-7\\S14-005_FRAMEWORK_AGREEMENT_FOR_ENGINE_MAINTENANCE_SERVICES_EASYJET[1]\\S14-005_FRAMEWORK_AGREEMENT_FOR_ENGINE_MAINTENANCE_SERVICES_EASYJET[1].txt", "4" ) != 0 ) {
            obj.iDRMSGEDll_Finalize();
            return;
        }
        System.out.println("iDRMSGEDll_ConvertFile 1 success.");
        /*if (obj.iDRMSGEDll_ConvertFile("C:\\Software\\iDRS_15_1_7_2304\\sample_pdfs\\scan1_200dpi.pdf", 
            "C:\\Software\\iDRS_15_1_7_2304\\sample_pdfs\\scan1_200dpi.out", 4) != 0 ) {
            obj.iDRMSGEDll_Finalize();
            return;
        }
        System.out.println("iDRMSGEDll_ConvertFile 2 success.");
        if (obj.iDRMSGEDll_ConvertFile("C:\\Software\\iDRS_15_1_7_2304\\sample_pdfs\\scan1_300dpi.pdf", 
            "C:\\Software\\iDRS_15_1_7_2304\\sample_pdfs\\scan1_300dpi.out", 4) != 0 ) {
            obj.iDRMSGEDll_Finalize();
            return;
        }
        System.out.println("iDRMSGEDll_ConvertFile 3 success.");
        if (obj.iDRMSGEDll_ConvertFile("C:\\Software\\iDRS_15_1_7_2304\\sample_pdfs\\scan2_300dpi.pdf", 
            "C:\\Software\\iDRS_15_1_7_2304\\sample_pdfs\\scan2_300dpi.out", 4) != 0 ) {
            obj.iDRMSGEDll_Finalize();
            return;
        }
        System.out.println("iDRMSGEDll_ConvertFile 4 success.");
        obj.iDRMSGEDll_Finalize();
        System.out.println("iDRMSGEDll_Finalize success.");
        return;*/

}
    public static String callOcr(String inputFile, String docType, String engineType, String filePath,String outputFolder,String type) throws RuntimeException
    {
        String message =  "";
        String formatType = type;           
        String inFile = filePath +"\\" +inputFile;
        String outFile="";
        if(type.equals("4"))
        outFile = outputFolder +"\\"+inputFile.substring(0,inputFile.lastIndexOf("."))+".txt";
        else if(type.equals("6"))
            outFile = outputFolder +"\\"+inputFile.substring(0,inputFile.lastIndexOf("."))+".rtf";
        else if(type.equals("9"))
            outFile = outputFolder +"\\"+inputFile.substring(0,inputFile.lastIndexOf("."))+".pdf";
        else
            outFile = outputFolder +"\\"+inputFile.substring(0,inputFile.lastIndexOf("."))+".csv";

        System.out.println("infile >> "+inFile);
        System.out.println("outFile >> "+outFile);
        System.out.println("Hello : This is java library path:(NICKRJ) " +System.getProperty("java.library.path"));

        System.loadLibrary("iDRMSGEBridgeDll");
        //System.load("C:\\Program Files (x86)\\I.R.I.S. SA\\iDRS_15_2_for_Win64_15_2_11_1717\bin\\iDRMSGEBridgeDll.dll");
        //Runtime.getRuntime().loadLibrary("iDRMSGEBridgeDll");

            iDRMSGEBridgeDll obj = new iDRMSGEBridgeDll();
        try
        {
            if ( obj.iDRMSGEDll_Initialize("D:\\IRIS\\iDRSGEDll.properties") != 0 ) {
                obj.iDRMSGEDll_Finalize();
            //  return ; 
            }
            System.out.println("iDRMSGEDll_Initialize success.");
            if ( obj.iDRMSGEDll_VerifyLicense() != 0 ) {
                obj.iDRMSGEDll_Finalize();
        //      return;
            }
            System.out.println("iDRMSGEDll_VerifyLicense success.");
        //  formatType= JOptionPane.showInputDialog("Please input mark format type: ");
            if (formatType!=null && formatType.equals("4"))  {
                obj.iDRMSGEDll_ConvertFile(inFile, 
                        outFile, "4" ); 
                obj.iDRMSGEDll_Finalize();
        //      return;
            }
            else if(formatType!=null && formatType.equals("6")) {
                obj.iDRMSGEDll_ConvertFile(inFile, 
                        outFile, "6" ); 
                    obj.iDRMSGEDll_Finalize();
            //      return;
                }   
            else if(formatType!=null && formatType.equals("7")) {
                obj.iDRMSGEDll_ConvertFile(inFile, 
                        outFile, "7" ); 
                    obj.iDRMSGEDll_Finalize();
            //      return;
                }
            else if(formatType!=null && formatType.equals("9")) {
                obj.iDRMSGEDll_ConvertFile(inFile, 
                        outFile, "9" ); 
                    obj.iDRMSGEDll_Finalize();
            //      return;
                }
            else
            {
            message= "iDRMSGEDll_VerifyLicense failure";
            }

            System.out.println("iDRMSGEDll_ConvertFile 1 success.");
            /*if (obj.iDRMSGEDll_ConvertFile("C:\\Software\\iDRS_15_1_7_2304\\sample_pdfs\\scan1_200dpi.pdf", 
                "C:\\Software\\iDRS_15_1_7_2304\\sample_pdfs\\scan1_200dpi.out", 4) != 0 ) {
                obj.iDRMSGEDll_Finalize();
                return;
            }
            System.out.println("iDRMSGEDll_ConvertFile 2 success.");
            if (obj.iDRMSGEDll_ConvertFile("C:\\Software\\iDRS_15_1_7_2304\\sample_pdfs\\scan1_300dpi.pdf", 
                "C:\\Software\\iDRS_15_1_7_2304\\sample_pdfs\\scan1_300dpi.out", 4) != 0 ) {
                obj.iDRMSGEDll_Finalize();
                return;
            }
            System.out.println("iDRMSGEDll_ConvertFile 3 success.");
            if (obj.iDRMSGEDll_ConvertFile("C:\\Software\\iDRS_15_1_7_2304\\sample_pdfs\\scan2_300dpi.pdf", 
                "C:\\Software\\iDRS_15_1_7_2304\\sample_pdfs\\scan2_300dpi.out", 4) != 0 ) {
                obj.iDRMSGEDll_Finalize();
                return;
            }
            System.out.println("iDRMSGEDll_ConvertFile 4 success.");*/
            obj.iDRMSGEDll_Finalize();
            System.out.println("iDRMSGEDll_Finalize success.");
            if(message.length()==0)
            {
                message = "success";
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
            message = e.getMessage();
        }

        return message;





    }


}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM