Para System.loadLibrary()
que funcione, la biblioteca (en Windows, una DLL) debe estar en un directorio en algún lugar de usted PATH
o en una ruta listada en la 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, /path/to/something.dll
solo usarías System.loadLibrary("something")
.
También necesita mirar exactamente lo UnsatisfiedLinkError
que está obteniendo. Si dice algo como:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path
entonces no puede encontrar la biblioteca foo (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()
llamada 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 anteriormente.
Como nota al margen, la mayoría de las personas colocan sus loadLibrary()
llamadas en un bloque inicializador estático en la clase con los métodos nativos, para asegurarse de que siempre se ejecute exactamente una vez:
class Foo {
static {
System.loadLibrary('foo');
}
public Foo() {
}
}
loadLibrary()
comentario - muy útil cuando no tiene idea de lo que está haciendo mal.lib
prefijo. Así queSystem.loadLibrary("foo")
necesitalibfoo.so
.blah.jnilib
y Linuxlibblah.so
. Bueno, dos horas después, después de numerosos intentos, llegué a la conclusión de que OSX también requierelib
prefijoCambiar la variable 'java.library.path' en tiempo de ejecución no es suficiente porque JVM solo la lee una vez. Tienes que restablecerlo como:
Por favor, obtenga un botín en: Changing Java Library Path at Runtime .
fuente
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:
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 volver a cargarla . 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:
Luego coloque un jar 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 manera tan simple como esto:
Ahora su DLL debe cargarse en el cargador de clases común y puede ser referenciado desde su aplicación web incluso después de volver a implementarlo.
¿Tener sentido?
Se puede encontrar una copia de referencia funcional en el código de Google, static-dll-bootstrapper .
fuente
Puede utilizar
System.load()
para proporcionar una ruta absoluta que es lo que desea, en lugar de un archivo en la carpeta de la biblioteca estándar para el sistema operativo respectivo.Si desea aplicaciones nativas que ya existen, use
System.loadLibrary(String filename)
. Si desea proporcionar el suyo, probablemente sea mejor con load ().También debería poder utilizarlo correctamente
loadLibrary
con eljava.library.path
conjunto. Consulte laClassLoader.java
fuente de implementación que muestra ambas rutas que se están verificando (OpenJDK)fuente
En el caso de que el problema sea que System.loadLibrary no puede encontrar la DLL en cuestión, un error común (reforzado por el mensaje de error de Java) es que la propiedad del sistema java.library.path es la respuesta. Si establece la propiedad del sistema java.library.path en el directorio donde se encuentra su DLL, System.loadLibrary encontrará su DLL. Sin embargo, si su DLL a su vez depende de otras DLL, como suele ser el caso, entonces java.library.path no puede ayudar, porque la carga de las DLL dependientes es administrada completamente por el sistema operativo, que no sabe nada de java.library. camino. Por lo tanto, casi siempre es mejor omitir java.library.path y simplemente agregar el directorio de su DLL a LD_LIBRARY_PATH (Linux), DYLD_LIBRARY_PATH (MacOS) o Path (Windows) antes de iniciar la JVM.
(Nota: estoy usando el término "DLL" en el sentido genérico de DLL o biblioteca compartida).
fuente
Si necesita cargar un archivo que es relativo a algún directorio donde ya se encuentra (como en el directorio actual), aquí tiene una solución fácil:
fuente
Para los que buscan
java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path
Me enfrentaba a la misma excepción; Probé todo y las cosas importantes para que funcione son:
Funcionó con tomcat 6.
fuente
Si cree que agregó una ruta de biblioteca nativa a
%PATH%
, intente probar con:Debería mostrarte si tu dll está activado
%PATH%
%PATH%
fuente
Pobre de mí ! Pasé un día entero detrás de esto. Escribiéndolo aquí si algún organismo replica este problema.
Estaba tratando de cargar como sugirió Adam, pero luego me atraparon con la excepción AMD64 vs IA 32.Si en cualquier caso, después de trabajar según el tutorial de Adam (sin duda la mejor opción), intente tener una versión de 64 bits del último jre. su JRE Y JDK son de 64 bits y lo ha agregado correctamente a su classpath.
Mi ejemplo de trabajo va aquí: error de enlace no declarado
fuente
Para Windows, descubrí que cuando cargué los archivos (llamadas jd2xsx.dll y ftd2xx.dll) en la carpeta windowws / system32, esto resolvió los problemas. Luego tuve un problema con mi nuevo fd2xx.dll que tenía que ver con los parámetros, por lo que tuve que cargar la versión anterior de este dll. Tendré que sacar esto más tarde.
Nota: jd2xsx.dll llama a ftd2xx.dll, por lo que es posible que la configuración de la ruta para jd2xx.dll no funcione.
fuente
Estoy usando Mac OS X Yosemite y Netbeans 8.02, obtuve el mismo error y la solución simple que encontré es como la anterior, esto es útil cuando necesita incluir una biblioteca nativa en el proyecto. Entonces haz lo siguiente para Netbeans:
Espero que pueda ser de utilidad para alguien. El enlace donde encontré la solución está aquí: java.library.path - ¿Qué es y cómo usarlo?
fuente
VM Options: java -Djava.library.path="your_path"
Tuve el mismo problema y el error se debió a un cambio de nombre de la dll. Podría suceder que el nombre de la biblioteca también esté escrito en algún lugar dentro de la dll. Cuando devolví su nombre original, pude cargar usando
System.loadLibrary
fuente
Es simple, simplemente escriba java -XshowSettings: properties en su línea de comando en Windows y luego pegue todos los archivos en la ruta mostrada por java.library.path.
fuente