Come correggere un UnsatisfiedLinkError (impossibile trovare le librerie dipendenti) in un progetto JNI

StackOverflow https://stackoverflow.com/questions/6092200

Domanda

Sto lavorando a un progetto Java che usa il JNI. Il JNI chiama una biblioteca personalizzata che ho scritto me stesso, diciamo MyLib.dll, e questo dipende da una biblioteca di terze parti, libsndfile-1.dll.

Quando eseguo il mio programma si blocca con

java.lang.UnsatisfiedLinkError:  C:\...path...\mylib.dll: Can't find dependent libraries.
.

Ho cercato questo sito (e altri) e ho provato un numero di correzioni:

    .
  1. Ho eseguito dependenze walker. DW ha dato un paio di avvertimenti - che due biblioteche richieste da libsndfile, mpr.dll e shlwapi.dll, avevano "importazioni irrisolte" - ma il DA DFAQ ha detto che questi avvertimenti potrebbero essere ignorati in modo sicuro.

  2. Ho riparato i nomi dei metodi in mylib.dll, come suggerito qui . I nomi dei metodi avevano in qualche modo ottenuto manglato dal compilatore, ma ho aggiunto flag di linker e i nomi dei metodi DLL ora corrispondono esattamente a quelli nel mio file di intestazione JNI esattamente.

  3. Metti tutte queste DLL nella stessa directory - la stessa directory del .jar che li chiama - per garantire che siano sul percorso giusto.

  4. nessun dado.

    Qualcuno ha qualche idea cosa sta succedendo?

    Sto facendo il mio sviluppo in Visual Studio 2010 su un MacBook Pro (via paralleli). Sto facendo i miei test in Windows XP su un laptop Toshiba.

È stato utile?

Soluzione

Sono abbastanza sicuro che il classpath e il percorso di ricerca della biblioteca condiviso abbiano poco da fare l'uno con l'altro. Secondo il libro JNI (che certo è vecchio ), Su Windows Se non si utilizza la proprietà del sistema java.library.path, la DLL deve essere nella directory di lavoro corrente o in una directory elencata nella variabile di ambiente PATH di Windows.


.

Aggiornamento:

Sembra che Oracle abbia rimosso il PDF dal suo sito web. Ho aggiornato il link sopra per indicare un'istanza del PDF Living presso l'Università del Texas - Arlington.

Inoltre, è anche possibile leggere la versione HTML di Oracle di Specifiche JNI . Ciò vive nella sezione Java 8 del sito Web Java e quindi spero che saranno in giro per un po '.


.

Aggiornamento 2:

Almeno in Java 8 (non ho controllato le versioni precedenti) puoi fare:

java -XshowSettings:properties -version
.

Per trovare il percorso di ricerca della biblioteca condivisa. Cerca il valore della proprietà java.library.path in quell'output.

Altri suggerimenti

Voglio informare questo caso interessante, dopo aver provato tutto il metodo sopra, l'errore è ancora lì.La cosa strana è funziona su un computer Windows 7, ma su Windows XP non lo è.Quindi uso Dependency Walker e ho trovato su Windows XP, non ci sono runtime VC ++ come requisito della mia DLL.Dopo aver installato VC ++ Runtime Package qui funziona come un fascino.La cosa che mi ha disturbato è che mantiene che non riesce a trovare le biblioteche dipendenti, mentre intuitivamente la DLL dipendente da JNI è lì, tuttavia finalmente risulta finalmente la DLL dipendente da JNI richiede un altro DL dipendente.Spero che questo aiuti.

È necessario caricare la tua libreria JNI.

System.loadLibrary carica la DLL daIl percorso JVM (PATH BIN JDK).

Se si desidera caricare un file esplicito con un percorso, utilizzare Sistema.Carica ()

Vedi anche: differenza tra sistema.load () eSystem.loadLibrary in Java

Verifica che il percorso della libreria sia giusto o meno.Naturalmente, è possibile utilizzare il seguente codice per controllare il percorso del percorso della libreria: System.out.println(System.getProperty("java.library.path"));

È possibile nominare il Java.Library.Path quando si avvia un'applicazione Java:

java -Djava.library.path=path ...
.

Se carichi una versione a 32 bit della DLL con un jre a 64 bit potresti avere questo problema.Questo è stato il mio caso.

ha avuto problemi identici con la macchina XP durante l'installazione di javacv e opencv in combinazione con Eclipse.Si è scoperto che mi mancavano i seguenti file:

    .
  • msvcp100.dll
  • msvcr100.dll

Una volta installati questi, il progetto ha compilato e correva OK.

    .
  • Risposta breve: per errore "Impossibile trovare la biblioteca dipendente", controlla il tuo percorso $ (corrisponde al punto di proiettile n. 3)
  • Risposta lunga:
      .
    1. Pure Java World: JVM utilizza "ClassPath" per trovare i file di classe
    2. JNI World (Java / Bordegliario nativo): JVM utilizza "Java.Library.Path" (che è predefinito fino a $ Path) per trovare DLLS
    3. Pure Native World: il codice nativo utilizza $ Path per caricare altre DLL

Ho trovato un grande articolo da alcuni amici a Keepsafe che ha attraversato la stessa cosa che ho fatto.Ha funzionato per me, quindi spero che ti aiuti anche tu!Avere una lettura se sei interessato ( I pericoli di caricare biblioteche native su Android ) o solo utilizzare

compile 'com.getkeepsafe.relinker:relinker:1.2.3'

e sostituisci

System.loadLibrary("myLibrary");
.

con

ReLinker.loadLibrary(context, "mylibrary");
.

Avevo esattamente lo stesso problema, e alla fine è stato risolto.

Metti tutte le DLL dipendenti nella stessa cartella in cui è stato memorizzato MyLib.dll e assicurati che il compilatore Java possa trovarlo (se non c'è MyLib.dll nel percorso di compilazione, ci sarebbe un errore che segnala questo durante la compilazione).La cosa importante che devi notare è che devi assicurarti che tutte le libs dipendenti siano della stessa versione con MyLib.dll, ad esempio se il tuo mylib.dll è la versione di rilascio, quindi dovresti anche mettere la versione di rilascio di tutte le sue libes dipendenti lì.

Spero che questo possa aiutare gli altri che hanno riscontrato lo stesso problema.

Ho avuto lo stesso problema, e ho provato tutto ciò che è stato pubblicato qui per aggiustarlo ma nessuno ha funzionato per me. Nel mio caso sto usando il cygwin per compilare la DLL.Sembra che JVM cerchi di trovare le DLL JRE nel percorso virtuale del cygwin. Ho aggiunto il percorso della directory virtuale di Cygwin a JRE's DLLS e funziona ora. Ho fatto qualcosa del genere:

.

Set Path="/ Cygdrive / C / Program Files / Java / JDK1.8.0_45";% PATH%

Nella mia situazione, stavo cercando di eseguire un servizio Web Java a Tomcat 7 tramite un connettore in Eclipse.L'app correva bene quando ho schierato il file di guerra in un'istanza di Tomcat 7 sul mio laptop.L'app richiede un driver di tipo 2 JDBC per "IBM DB2 9.5".Per un motivo strano il connettore in Eclispi non è stato possibile vedere o utilizzare i percorsi nelle variabili dell'ambiente IBM DB2, per raggiungere i file DLL installati sul mio laptop come client JCC.Il messaggio di errore ha dichiarato che non è riuscito a trovare il file DB2JCCT2 DLL o non è riuscito a trovare le librerie dipendenti per quel file DLL.In definitiva, ho cancellato il connettore e l'ho ricostruito.Quindi ha funzionato correttamente.Sto aggiungendo questa soluzione qui come documentazione, perché non ho trovato questa soluzione specifica da nessun'altra parte.

Creare la libreria statica ha funzionato per me, compilando usando g++ -static.Si fa impacchettare le biblioteche dipendenti insieme alla build.

Installazione di Microsoft Visual C ++ 2010 SP1 Ridistribuibile IT

Posizionare le DLL richieste nella cartella e impostare il percorso della cartella nella variabile dell'ambiente del percorso. Assicurarsi che la variabile del percorso dell'ambiente aggiornata venga riflessa.

Stavo affrontando lo stesso problema con la libreria FFMpeg dopo aver unito due progetti Android come un unico progetto.

Il problema effettivamente è stato arrivato a causa di due diverse versioni della libreria FFMPEG, ma sono state caricate con lo stesso nomi in memoria.Una biblioteca è stata inserita in Jnilibs mentre l'altro era all'interno di un'altra biblioteca utilizzata come modulo.Non sono stato in grado di modificare il codice del modulo come è stato readyly, quindi ho ribattezzato quello usato nel mio codice per ffmpegcamera e lo ha caricato in memoria con lo stesso nome.

System.loadLibrary("ffmpegCamera");
.

Questo risolto il problema e ora entrambe le versioni delle librerie stanno caricando bene come nome separato e ID processo in memoria.

    .
  1. Vai a http://tess4j.sourceforge.net/usage.html e fare clic susu Visual C++ Redistributable for VS2012
  2. Scaricalo ed esegui VSU_4\vcredist_x64.exe o VSU_4\vcredist_x84.exe a seconda della configurazione del sistema
  3. Metti i file dll all'interno della cartella lib, insieme alle altre librerie (ad es. \lib\win32-x86\your dll files).
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top