2010-06-18 7 views
7

Aus irgendeinem Grund erhalte ich in meiner Java-App einen lästigen Unbefriedigten Link-Fehler.Unzufriedener Linkfehler bei Verwendung von System.loadLibrary()?

Dies ist der Täter in Frage:

System.loadLibrary("psjw"); 

Trotz der Bibliothek psjw.dll in dem gleichen Quelle Paket wie diese Klasse eindeutig zu sein.

Bitte helfen.

+1

Sie könnten mit System.load betrachten(). Es benötigt einen vollständig qualifizierten Pfad und ignoriert alle Umgebungsvariablen. Es ist nur: 'System.load (" C: \\ Programme \\ Meine große Programm \\ libs \\ psjw.dll ");' Beachten Sie, dass Sie die Zeichenfolge mit dem Pfad zur Laufzeit erstellen können, so Sie können zuerst nach Dingen wie dem Benutzerverzeichnis, dem Verzeichnis, in dem Ihr Programm installiert ist, und so weiter fragen. Dies ist möglicherweise besser zu loadLibrary(), da Sie nie wissen, ob etwas in der Liste der Orte, die bereits durchsucht werden, den Namen "psjw.dll, "was dazu führen könnte, dass man eine Bibliothek lädt, die man nicht kannte. –

+0

Danke für diesen Kommentar, wirklich gut, um die Ursache eines Problems mit einer Bibliothek zu finden –

Antwort

3

Try explicity den Bibliothekspfad zu setzen, wenn die JVM Start: -Djava.library.path="Directory of DLL"

4

Sicherstellen, dass der psjw.dll entweder auf Ihrem Weg oder java.library.path ist.

Ex: psjw.dll kann in/usr/lib werden dann Ihren Befehl java würde -Djava.library.path =/usr/lib ur.package.UrClass

Testen Sie Ihr Setup nach unten ein gestrippt mit Klasse:

public class TestLoadLibrary { 

    public static void main(String[] args) { 

     String libPath = System.getProperty("java.library.path"); 
     System.out.println("java.library.path=" + libPath); 

     String libraryName = "psjw"; 
     System.out.println("Trying to load '" + libraryName + "'"); 
     System.loadLibrary(libraryName); 
    } 
} 
+0

Nun, ich verstehe, dass die DLL in der sein muss classpath, um zu verweisen, und es ist. Sollte der .jar-Klassenpfad standardmäßig nicht auf die .jar festgelegt werden, da das Kompilieren und das Ausführen der .jar keine Hilfe ist –

+2

Die DLL muss in dem Pfad des Prozesses sein, der versucht, zu laden Die DLL in den Speicher. Java verwendet CLASSPATH, um Klassen zu finden. Der Loader des Betriebssystems verwendet PATH (unter Windows), um DLLs zu finden, die Sie dynamisch laden möchten. –

+1

@Aaron - Wie Brian sagte, gibt es zwei verschiedene Dinge bei der Arbeit. CLASSPATH ist vollständig getrennt von PATH oder java.library.path.CLASSPATH zeigt auf jars/classes, PATH oder java.library.path auf die Verzeichnisse ausführbarer Dateien/dlls – DeezCashews

0

Was kann ich aus meiner Erfahrung sagen, dass, wenn die LOADLIB (bibliotheks) aus statischen Initialisierungsbaustein in Java-Klasse-Datei ausgeführt wird, sollte die libraray existiert in java.library.path sein. Andernfalls kann die Klasse nicht geladen werden. Wenn wir den loadLibrary() -Aufruf jedoch unter anderen Methoden, z. B. Main(), verschieben, kann er aus dem Umgebungspfad gelesen werden.

0

Ich habe an diesem Thema für zwei Tage gearbeitet, aber ich fand schließlich die Antwort. Zuerst habe ich ein Verzeichnis für Bibliotheken erstellt und die Umgebungsvariable PATH auf dieses Verzeichnis gesetzt. Ich mag es aber nicht, meinen Weg zu verstopfen, also gebe ich dir jetzt das, was ich bei http://blog.cedarsoft.com/2010/11/setting-java-library-path-programmatically/ gefunden habe. Meine Wiedergabe folgt

package yourpackage; 

import java.io.File; 
import java.lang.reflect.Field ; 

public class YourClass { 
    public native void print() ; 
    static 
    { 
     String mPath = new File (".").getAbsolutePath() ; 
     String langKey = "java.library.path" ; 
     System.setProperty (langKey, mPath) ; 

     // Tested both with and without the following, and worked either way. 
/*  try 
     { 
      Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); 
      fieldSysPath.setAccessible(true); 
      fieldSysPath.set(null, null); 
     } 
     catch (NoSuchFieldException e) 
     { 
      System.err.println ("Unable to reset system path field: \n" + e + '\n') ; 
     } 
     catch (IllegalAccessException e) 
     { 
      System.err.println ("Unable to access system path after reset: \n" 
        + e + '\n') ; 
     } */ 

     try 
     { 
      System.loadLibrary ("YourLibrary") ; 
     } 
     catch (UnsatisfiedLinkError e) 
     { 
      System.err.println ("Native code library failed to load.\n" + e) ; 
      System.exit (1) ; 
     } 

    } 

    public static void main (String[] args) 
    { 
     YourClass yc = new YourClass() ; 
     yc.print(); 
    } 
} 

Für den obigen Code Ihre DLL im selben Ordner wie die .java sein muss. Wenn Sie über die Befehlszeile ausgeführt werden, denken Sie daran, dass Sie aus demselben Verzeichnis für javac und root-Paketverzeichnis für Java-Aufrufe aufrufen. So für die .java ist C: \ Arbeitsplatz \ yourpackage \ YourClass.java, Sie von der Kommandozeile aufrufen:

cd "C:\workspace" 
java yourpackage.YourClass 
2

Für eine korrekte Nachschlag von Bibliothek (von java.library.path) für verschiedene OS muss die haben verschiedene Namen:

  • Linux: libpsjw.so
  • Fenster: psjw.dll

als Sie von Java anrufen:

System.loadLibrary("psjw");