2011-07-26 19 views
9

estoy usando el siguiente código para cargar un archivo DLL en JNA (código irrelevante se queda fuera):JNA UnsatisfiedLinkError, pero jna.library.path se establece

public class JNAMain { 
     public interface PointShapeBuffer extends Library { ... } 

     public static void main(String[] args){ 
      System.setProperty("jna.library.path", "c:\\jnadll"); 
      System.setProperty("java.library.path", "c:\\jnadll"); 

      PointShapeBuffer jna = (PointShapeBuffer) Native.loadLibrary("FileGDBAPI", PointShapeBuffer.class); 
     } 
    } 

Y me sale el siguiente error:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'FileGDBAPI': The specified module could not be found. 

También he intentado configurar los argumentos VM. Cualquier sugerencia seria genial.

Editar: Como referencia, estoy usando una biblioteca disponible públicamente here (es necesario registrarse).

+0

¿Ventanas? Linus? PATH configurado para incluir lib compartido en Windows? LD_LIBRARY_PATH en Linux? – bmargulies

+0

Esto es Windows 7. La variable de entorno PATH se ha cambiado para incluir "C: \ jnadll", pero sigo recibiendo el error. – Dave86

+0

Mismo problema aquí. Puedo cargar user32.dll muy bien, pero vomita al tratar de cargar cualquier archivo DLL de Windows de 32 bits, sin importar dónde los ponga/cómo les señalo la ruta. –

Respuesta

2

Debe especificar la carpeta que contiene su DLL, no la ruta real de la DLL.

p. Ej. para baz.dll en c:\foo\bar\baz.dll, la ruta debe establecerse en c:\\foo\\bar. (tenga en cuenta que en Java si está utilizando espacios inversos, tendrá que escapar con barras invertidas)

+0

Disculpa por abstraer la ruta del archivo. No quería regalar nada confidencial en mi máquina de trabajo. El dll está ahora en C: \ jnadll \ FileGDBAPI.dll, pero establecer las rutas a "c: \\ jnadll" sigue siendo un no ir. – Dave86

+1

@Dave: ¿ha intentado configurar las propiedades del sistema durante la llamada al programa en lugar de hacerlo en main? ('-Djna.library.path = c: \ jnadll') –

+0

Desafortunadamente eso tampoco funcionó. Utilicé Dependency Walker para ver si faltaban referencias y me arrojó este error: "Se encontraron módulos con diferentes tipos de CPU". Esto fue para gpsvc.dll y sysntfy.dll, ambos de 64 bits. No puedo encontrar versiones de 32 bits, así que estoy atascado nuevamente. – Dave86

1

Es posible que desee descargar la última versión con jna.jar y platform.jar y simplemente incluirlos. No es necesario establecer el camino entonces.

8

En mi experiencia, normalmente ve este error al llamar a dlls nativos de 32 bits desde un jvm de 64 bits en Win7 de 64 bits. Win7 funciona de manera diferente para aplicaciones de 64 bits y 32 bits.

En 64bit Win7 puede llamar a funciones en dll nativos de 32 bits, pero necesita usar una JVM de 32 bits.

  1. Descargue e instale Java Runtime Environment (JRE) de 32 bits. Puede instalar un jvm de 32 bits y 64 bits en la misma máquina, solo asegúrese de que estén instalados en directorios separados.
  2. Asegúrese de ejecutar el JRE de 32 bits en lugar de la JVM de 64 bits predeterminada cuando ejecuta su programa. O bien A) cambie las variables de entorno CLASSPATH y JAVA_HOME para que apunten a la jvm de 32 bits, o escriba una secuencia de comandos para establecer CLASSPATH y JAVA_HOME y lance su aplicación.

La razón de esto es que los discos dll de 32 bits son incompatibles con las aplicaciones de 64 bits, y los de 64 bits Win7 usan un emulador de 32 bits para ejecutar aplicaciones de 32 bits. Aunque las bibliotecas de Windows pueden llamarse xxxx32.dll (por ejemplo, user32.dll), las bibliotecas de la carpeta System32 en un Win7 de 64 bits son bibliotecas de 64 bits, no de 32 bits, y las bibliotecas de SysWOW64 son bibliotecas de 32 bits, ¿no es cierto?

También puede colocar la biblioteca en la carpeta del sistema de 32 bits (SysWOW64) y realizar la llamada JNI desde una JVM de 32 bits.

Consulte el siguiente enlace para obtener una explicación completa de cómo WinBS de 64 bits maneja las bibliotecas;

http://www.samlogic.net/articles/32-64-bit-windows-folder-x86-syswow64.htm

Y si realmente quiere ayudarse a sí mismo a conciliar el sueño, tratando de iniciar en este;)

http://msdn.microsoft.com/en-us/windows/hardware/gg463051.aspx

4

Cambia tu:

Native.loadLibrary("FileGDBAPI", PointShapeBuffer.class); 

a:

Native.loadLibrary("C:\\jnadll\\FileGDBAPI.dll", PointShapeBuffer.class); 

Si bucea en el código fuente lo suficientemente JNA se encuentra un pequeño gancho agradable en la clase nativeLibrary:

/** Use standard library search paths to find the library. */ 
    private static String findLibraryPath(String libName, List searchPath) { 
     // 
     // If a full path to the library was specified, don't search for it 
     // 
     if (new File(libName).isAbsolute()) { 
      return libName; 
     } 
     ... 

Así se captura si acaba de pasar una ruta absoluta y ni siquiera usar el SearchPath. Por eso no tienes que preocuparte por jna.library.lib.

+0

Esto es lo que comencé a hacer y no funcionó. –

+0

No sé qué decirle ... tal vez usted tenga una versión diferente de jna. Esto ha funcionado para mí y para otros, y el código fuente (copiado de mi versión de jna) no miente. – JHowIX

+1

Resulta que el JNA no distingue entre * no poder encontrar el dll * y * no ser capaz de encontrar dependencias dll *. Así que la DLL estaba bien, pero me faltaba la dependencia, como descubrí usando el walker de dependencias. –

-1

puede ser porque existe una combinación en el kit de lebweb. No estoy seguro, pero tiene que ser que solo ahora puedes hacer una cosa, prueba esto.

$ dpkg -l | grep -i jna 

tratar este comando y si u obtener esta salida

ii libjna-java 3.2.7-4 Dynamic access of native libraries from Java without JNI 

o cualquier otra salida, entonces este u necesidad de retirar entonces que JNA del sistema, porque si el programa en sí tiene frasco JNA con que entonces hay no hay necesidad de sistema jna para lo mismo. haz algo como esto

sudo apt-get autoremove libjna-java 

y trate de reiniciar esa aplicación nuevamente. se ejecutará y no se está ejecutando, intente instalar la nueva versión de libwebkit-gtk.

Espero que esto ayude. esto me ayudó.

Cuestiones relacionadas