2010-06-18 10 views
7

Por alguna razón, recibo un molesto Error de enlace insatisfecho en mi aplicación java.Error de enlace insatisfecho al usar System.loadLibrary()?

Este es el delincuente en cuestión:

System.loadLibrary("psjw"); 

A pesar de la psjw.dll biblioteca que se está claramente en el mismo paquete fuente que esta clase.

Por favor ayuda.

+1

Se podría considerar el uso de System.load(). Toma una ruta completamente calificada e ignora todas las variables ambientales. Es solo: 'System.load (" C: \\ Archivos de programa \\ Mi gran programa \\ libs \\ psjw.dll ");' Tenga en cuenta que puede crear la cadena con la ruta en tiempo de ejecución, por lo puede consultar primero para cosas como el directorio del usuario, el directorio donde está instalado su programa, etc. Esto podría ser preferible a loadLibrary(), ya que nunca se sabe si algo en la lista de lugares que busca ya tiene el nombre "psjw".dll, "que podría terminar cargando una biblioteca que no sabías que estaba allí. –

+0

Gracias por ese comentario, realmente bueno para descubrir la causa raíz de un problema con una biblioteca –

Respuesta

3

intenta establecer explícitamente la ruta de la biblioteca cuando se inicia la JVM: -Djava.library.path="Directory of DLL"

4

Asegúrese de que el psjw.dll está bien en su camino o java.library.path.

Ex: psjw.dll puede estar en/usr/lib luego sería su comando java Djava.library.path =/usr/lib ur.package.UrClass

Comprobación de la configuración utilizando una simplificada clase:

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

Bueno, entiendo que la DLL debe estar en el classpath para referenciar, y lo es. ¿No debería la vía de acceso de clases .jar por defecto establecerse en .jar? Porque compilarla y ejecutar .jar no es de ayuda. –

+2

La DLL debe estar en la RUTA del proceso que intenta cargar el DLL en la memoria. Java usa CLASSPATH para buscar clases. El cargador del sistema operativo usa PATH (en Windows) para encontrar archivos DLL que está intentando cargar dinámicamente. –

+1

@ Aaron - Como dijo Brian, aquí hay dos cosas diferentes que funcionan. CLASSPATH está completamente separado de PATH o java.library.path. CLASSPATH apunta a jar/clases, PATH o java.library.path a ubicaciones de ejecutables/dlls. – DeezCashews

0

lo que puedo decir de mi experiencia es que, si el loadlib (libraryname) se lleva a cabo desde el bloque de inicialización estática en el archivo de clase java, el libraray debe ser existe en java.library.path. De lo contrario, no se puede cargar la clase. Pero si movemos la llamada loadLibrary() a otros métodos, por ejemplo Main(), se puede leer desde la ruta del entorno.

0

He estado trabajando en este mismo problema durante dos días, pero finalmente encontré la respuesta. Primero creé un directorio para bibliotecas y establecí la variable de entorno PATH en ese directorio. Aunque no me gusta obstruir mi camino, ahora le doy lo que encontré al http://blog.cedarsoft.com/2010/11/setting-java-library-path-programmatically/. Mi interpretación sigue

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

Para el código anterior el archivo DLL tiene que estar en la misma carpeta que el .java. Si está ejecutando desde la línea de comandos, recuerde que llama desde el mismo directorio para javac, y el directorio del paquete raíz para llamar a Java. Así, para el .java ser C: \ workspace \ yourpackage \ YourClass.java, se llama desde la línea de comandos:

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

Para una correcta las operaciones de búsqueda de biblioteca (de java.library.path) para diferentes OS debe tener diferentes nombres:

  • Linux: libpsjw.so
  • de Windows: psjw.dll

de lo que puede llamar desde Java:

System.loadLibrary("psjw"); 
Cuestiones relacionadas