Saltar al contenido

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

Solución:

Para poder System.loadLibrary() para que funcione, la biblioteca (en Windows, una DLL) debe estar en un directorio en algún lugar de su PATH o en una ruta enumerada en el java.library.path propiedad del sistema (para que pueda iniciar Java como java -Djava.library.path=/path/to/dir).

Además, para loadLibrary(), especifica el nombre base de la biblioteca, sin el .dll al final. Entonces, para /path/to/something.dll, solo usarías System.loadLibrary("something").

También necesitas mirar el exacto UnsatisfiedLinkError que estás recibiendo. Si dice algo como:

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

entonces no puede encontrar el foo biblioteca (foo.dll) en su PATH o java.library.path. Si dice algo como:

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

entonces algo anda mal con la propia biblioteca en el sentido de que Java no puede mapear una función nativa de Java en su aplicación a su contraparte nativa real.

Para empezar, pondría algunos registros alrededor de su System.loadLibrary() llamar para ver si se ejecuta correctamente. Si arroja una excepción o no está en una ruta de código que realmente se ejecuta, siempre obtendrá el último tipo de UnsatisfiedLinkError explicado arriba.

Como nota al margen, la mayoría de la gente pone su loadLibrary() llamadas a un bloque inicializador estático en la clase con los métodos nativos, para garantizar que siempre se ejecute exactamente una vez:

class Foo {

    static {
        System.loadLibrary('foo');
    }

    public Foo() {
    }

}

Cambiar la variable ‘java.library.path’ en tiempo de ejecución no es suficiente porque JVM solo la lee una vez. Tienes que restablecerlo como:

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

Por favor, obtenga un botín en: Changing Java Library Path at Runtime.

La respuesta original de Adam Batkin lo llevará a una solución, pero si vuelve a implementar su aplicación web (sin reiniciar su contenedor web), debería encontrarse con el siguiente error:

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)

Esto sucede porque el ClassLoader que originalmente cargó su DLL todavía hace referencia a este DLL. Sin embargo, su aplicación web ahora se está ejecutando con un nuevo ClassLoader, y debido a que se está ejecutando la misma JVM y una JVM no permitirá 2 referencias a la misma DLL, no puede recargar eso. Por lo tanto, su aplicación web no puede acceder a la DLL existente y no puede cargar una nueva. Entonces … estás atascado.

La documentación de ClassLoader de Tomcat describe por qué su aplicación web recargada se ejecuta en un nuevo ClassLoader aislado y cómo puede evitar esta limitación (a un nivel muy alto).

La solución es extender un poco la solución de 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) {
        }

    }

Luego, coloque un frasco que contenga SOLO esta clase compilada en la carpeta TOMCAT_HOME / lib.

Ahora, dentro de su aplicación web, solo tiene que obligar a Tomcat a hacer referencia a esta clase, lo que se puede hacer de la siguiente manera:

  Class.forName("awesome.Foo");

Ahora su DLL debe cargarse en el cargador de clases común y se puede hacer referencia a ella desde su aplicación web incluso después de volver a implementarla.

¿Tener sentido?

Se puede encontrar una copia de referencia funcional en el código de Google, static-dll-bootstrapper.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *