java.lang.UnsatisfiedLinkError no *****. dll in java.library.path

Come posso caricare un file dll personalizzato nella mia applicazione web? Ho provato a seguire modi ma il suo fallimento.

  • copiato tutte le dll richieste nella cartella system32 e provato a caricarne una nel costruttore System.loadLibrary Servlet
  • DLL richieste copiate in tomcat_home/shared/lib e tomcat_home/common/lib
  • tutte queste DLL sono in WEB-INF/lib dell’applicazione web

Affinché System.loadLibrary() funzioni, la libreria (su Windows, una DLL) deve trovarsi in una directory da qualche parte sul PATH o su un percorso elencato nella proprietà di sistema java.library.path (in modo da poter avviare Java come java -Djava.library.path=/path/to/dir ).

Inoltre, per loadLibrary() , si specifica il nome base della libreria, senza la .dll alla fine. Quindi, per /path/to/something.dll , dovresti semplicemente usare System.loadLibrary("something") .

È inoltre necessario esaminare l’errore UnsatisfiedLinkError che si sta ottenendo. Se dice qualcosa del tipo:

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

quindi non riesce a trovare la libreria foo (foo.dll) nel PATH o java.library.path . Se dice qualcosa del tipo:

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

quindi qualcosa non va con la libreria stessa nel senso che Java non è in grado di mappare una funzione Java nativa nella tua applicazione alla sua controparte nativa.

Per cominciare, metterei un po ‘di logging sulla tua chiamata System.loadLibrary() per vedere se ciò avvenga correttamente. Se lancia un’eccezione o non si trova in un percorso di codice che viene effettivamente eseguito, otterrete sempre l’ultimo tipo di UnsatisfiedLinkError spiegato sopra.

Come sidenote, la maggior parte delle persone mette le loadLibrary() chiamate loadLibrary() in un blocco di inizializzazione statico nella class con i metodi nativi, per garantire che venga sempre eseguita esattamente una volta:

 class Foo { static { System.loadLibrary('foo'); } public Foo() { } } 

La risposta originale di Adam Batkin ti porterà a una soluzione, ma se ridistribuisci la tua webapp (senza riavviare il tuo contenitore web), dovresti incontrare il seguente errore:

 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) 

Ciò accade perché il ClassLoader che ha originariamente caricato la DLL fa ancora riferimento a questa DLL. Tuttavia, la tua webapp è ora in esecuzione con un nuovo ClassLoader, e poiché la stessa JVM è in esecuzione e una JVM non consentirà 2 riferimenti alla stessa DLL, non è ansible ricaricarla . Pertanto, la tua webapp non può accedere alla DLL esistente e non può caricarne una nuova. Quindi … sei bloccato.

La documentazione di Classcader di Tomcat illustra perché la webapp ricaricata viene eseguita in un nuovo ClassLoader isolato e come è ansible aggirare questa limitazione (ad un livello molto alto).

La soluzione è quella di estendere un po ‘la soluzione di 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) { } } 

Quindi posizionando un jar contenente JUST questa class compilata nella cartella TOMCAT_HOME / lib.

Ora, all’interno della tua webapp, devi solo forzare Tomcat a fare riferimento a questa class, operazione che può essere eseguita semplicemente come segue:

  Class.forName("awesome.Foo"); 

Ora la DLL deve essere caricata nel classloader comune e può essere referenziata dalla webapp anche dopo essere stata ridistribuita.

Ha senso?

Una copia di riferimento funzionante può essere trovata su google code, static-dll-bootstrapper .

La modifica della variabile ‘java.library.path’ in fase di runtime non è sufficiente perché viene letta una sola volta da JVM. Devi resettarlo come:

 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); 

Per favore, prendi un bottino su: Modifica del percorso della libreria Java in runtime .

È ansible utilizzare System.load() per fornire un percorso assoluto che è ciò che si desidera, piuttosto che un file nella cartella della libreria standard per il rispettivo sistema operativo.

Se si desiderano applicazioni native già esistenti, utilizzare System.loadLibrary(String filename) . Se vuoi fornire il tuo, probabilmente stai meglio con load ().

Dovresti anche essere in grado di utilizzare loadLibrary con java.library.path impostato correttamente. Vedi ClassLoader.java per l’origine di implementazione che mostra entrambi i percorsi controllati (OpenJDK)

Nel caso in cui il problema è che System.loadLibrary non riesce a trovare la DLL in questione, un equivoco comune (rafforzato dal messaggio di errore di Java) è che la proprietà di sistema java.library.path è la risposta. Se si imposta la proprietà di sistema java.library.path nella directory in cui si trova la DLL, System.loadLibrary troverà effettivamente la DLL. Tuttavia, se la DLL a sua volta dipende da altre DLL, come spesso accade, quindi java.library.path non può essere d’aiuto, poiché il caricamento delle DLL dipendenti è gestito interamente dal sistema operativo, che non conosce nulla di java.library. sentiero. Pertanto, è quasi sempre meglio ignorare java.library.path e aggiungere semplicemente la directory della DLL a LD_LIBRARY_PATH (Linux), DYLD_LIBRARY_PATH (MacOS) o Path (Windows) prima di avviare la JVM.

(Nota: sto usando il termine “DLL” nel senso generico di DLL o libreria condivisa).

Per coloro che cercano java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path

Stavo affrontando la stessa eccezione; Ho provato tutto e le cose importanti per farlo funzionare sono:

  1. Versione corretta di pdf lib.jar (Nel mio caso si trattava di una versione errata del jar mantenuta nel runtime del server)
  2. Crea una cartella e mantieni il barattolo di pdflib e aggiungi la cartella nella variabile PATH

Ha funzionato con Tomcat 6.

Povero me ! trascorso un’intera giornata dietro a questo. Scrittura qui se un qualsiasi corpo replica questo problema.

Stavo cercando di caricare come suggerito da Adam, ma poi sono stato colto con AMD64 vs IA 32 exception.Se in ogni caso dopo aver lavorato come Adam (senza dubbio il miglior pick-through), prova ad avere una versione a 64 bit dell’ultimo jre.Fake il tuo JRE e JDK sono 64 bit e lo hai correttamente aggiunto al tuo classpath.

Il mio esempio di lavoro va qui: errore di collegamento insoddisfatto

Se è necessario caricare un file relativo ad una directory in cui ci si trova già (come nella directory corrente), ecco una soluzione semplice:

 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()); 

Per Windows ho scoperto che quando ho caricato i filles (chiamate jd2xsx.dll e ftd2xx.dll) nella cartella windowws / system32 questo ha risolto i problemi. Ho quindi avuto un problema con il mio nuovo fd2xx.dll che ha a che fare con i parametri, motivo per cui ho dovuto caricare la versione precedente di questa dll. Dovrò farlo più tardi.

Nota: jd2xsx.dll chiama ftd2xx.dll, quindi l’impostazione del percorso per jd2xx.dll potrebbe non funzionare.

Sto usando Mac OS X Yosemite e Netbeans 8.02, ho ricevuto lo stesso errore e la soluzione semplice che ho trovato è come sopra, questo è utile quando devi includere la libreria nativa nel progetto. Quindi fai il prossimo per 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= 6.- Ok 

Spero possa essere utile per qualcuno. Il link in cui ho trovato la soluzione è qui: java.library.path – Che cos’è e come si usa

 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\IRIS SA\iDRS_15_2_for_Win64_15_2_11_1717\lib\idrskr .lib C:\Program Files\IRIS SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSG idgeDll.dll C:\Program Files\IRIS 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\IRIS SA\iDRS_15_2_for_Win64_15_2_11_1717\lib\idrskrn15.lib;C:\Program Files\IRIS SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSGEBridgeDll.dll;C:\Program Files\IRIS 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)\\IRIS 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; } }