Estoy trabajando en un proyecto de Java que usa JNI. El JNI llama a una biblioteca personalizada que yo mismo escribí, digamos mylib.dll, y eso depende de una biblioteca de terceros, libsndfile-1.dll.
Cuando ejecuto mi programa, se bloquea
java.lang.UnsatisfiedLinkError: C:\...path...\mylib.dll: Can't find dependent libraries.
Busqué en este sitio (y en otros) y probé varias correcciones:
Ejecuté el andador de la dependencia. DW dio un par de advertencias - que dos bibliotecas requeridas por libsndfile, MPR.DLL y SHLWAPI.DLL, tenían "importaciones no resueltas" - pero las preguntas frecuentes de DW dijeron que estas advertencias podían ignorarse sin peligro.
Arreglé los nombres de los métodos en mylib.dll, como se sugiere aquí . El compilador había alterado los nombres de los métodos de alguna manera, pero agregué indicadores del enlazador y los nombres de los métodos dll ahora coinciden exactamente con los de mi archivo de encabezado jni.
Pongo todas estas DLL en el mismo directorio, el mismo directorio que el .jar que las llama, para asegurarme de que estén en la RUTA correcta.
No dados.
¿Alguien tiene alguna idea de lo que está pasando?
Estoy haciendo mi desarrollo en Visual Studio 2010 en una MacBook pro (a través de Parallels). Estoy haciendo mis pruebas en Windows XP en una computadora portátil Toshiba.
Respuestas:
Estoy bastante seguro de que la ruta de clase y la ruta de búsqueda de la biblioteca compartida tienen poco que ver entre sí. Según The JNI Book (que ciertamente es antiguo), en Windows, si no usa la
java.library.path
propiedad del sistema, la DLL debe estar en el directorio de trabajo actual o en un directorio listado en laPATH
variable de entorno de Windows .Actualizar:
Parece que Oracle ha eliminado el PDF de su sitio web. Actualicé el enlace anterior para señalar una instancia del PDF que vive en la Universidad de Texas - Arlington.
Además, también puede leer la versión HTML de Oracle de la especificación JNI . Eso vive en la sección Java 8 del sitio web de Java y, por lo tanto, con suerte estará disponible por un tiempo.
Actualización 2:
Al menos en Java 8 (no he comprobado versiones anteriores) puede hacer:
para encontrar la ruta de búsqueda de la biblioteca compartida. Busque el valor de la
java.library.path
propiedad en esa salida.fuente
CLASSPATH
no se usa en absoluto. Tampoco estoy seguro de quecwd
se use en absoluto.java.library.path
o simplementePATH
funcionará. @dB ', el lugar donde los tiene ahora es incorrecto .Quiero informar este interesante caso, después de probar todo el método anterior, el error sigue ahí. Lo extraño es que funciona en una computadora con Windows 7, pero en Windows XP no. Luego utilizo el andador de dependencia y descubrí que en Windows XP no hay VC ++ Runtime como requisito de mi dll. Después de instalar el paquete VC ++ Runtime aquí , funciona como un encanto. Lo que me molestó es que sigue diciendo No se pueden encontrar bibliotecas dependientes, mientras que intuitivamente la dll dependiente de JNI está ahí, sin embargo, finalmente resulta que la dll dependiente de JNI requiere otra dl dependiente. Espero que esto ayude.
fuente
Necesita cargar su biblioteca JNI.
System.loadLibrary carga la DLL desde la ruta JVM (ruta bin JDK).
Si desea cargar un archivo explícito con una ruta, use System.load ()
Ver también: Diferencia entre System.load () y System.loadLibrary en Java
fuente
Verifique que la ruta de su biblioteca sea correcta o no. Por supuesto, puede usar el siguiente código para verificar la ruta de su biblioteca:
System.out.println(System.getProperty("java.library.path"));
Puede designar java.library.path al iniciar una aplicación Java:
fuente
Si carga una versión de 32 bits de su dll con un JRE de 64 bits, podría tener este problema. Este fue mi caso.
fuente
chromedriver.exe
el controlador Selenium para Chrome, que por lo que puedo decir solo viene en la versión de 32 bits.Tuve un problema idéntico con la máquina XP al instalar
javacv
yopencv
en combinación con Eclipse. Resultó que me faltaban los siguientes archivos:Una vez instalados, el proyecto se compiló y se ejecutó correctamente.
fuente
fuente
Encontré un gran artículo de algunos amigos en keepsafe que pasó por lo mismo que yo. Me funcionó, ¡así que espero que también te ayude! Lea si está interesado ( Los peligros de cargar bibliotecas nativas en Android ) o simplemente use
compile 'com.getkeepsafe.relinker:relinker:1.2.3'
y reemplazar
System.loadLibrary("myLibrary");
con
ReLinker.loadLibrary(context, "mylibrary");
fuente
Solía tener exactamente el mismo problema y finalmente se resolvió.
Pongo todas las DLL dependientes en la misma carpeta donde se almacenó mylib.dll y me aseguro de que el compilador JAVA pueda encontrarlo (si no hay mylib.dll en la ruta de compilación, habría un error al informar esto durante la compilación). Lo importante que debe tener en cuenta es que debe asegurarse de que todas las bibliotecas dependientes sean de la misma versión que mylib.dll, por ejemplo, si mylib.dll es la versión de lanzamiento, también debe colocar la versión de lanzamiento de todas sus bibliotecas dependientes allí. .
Espero que esto pueda ayudar a otros que se han encontrado con el mismo problema.
fuente
Tuve el mismo problema e intenté todo lo que se publica aquí para solucionarlo, pero ninguno funcionó para mí. En mi caso, estoy usando Cygwin para compilar el dll. Parece que JVM intenta encontrar las DLL de JRE en la ruta virtual de Cygwin. Agregué la ruta del directorio virtual de Cygwin a las DLL de JRE y ahora funciona. Hice algo como:
fuente
En mi situación, estaba intentando ejecutar un servicio web java en Tomcat 7 a través de un conector en Eclipse. La aplicación funcionó bien cuando implementé el archivo war en una instancia de Tomcat 7 en mi computadora portátil. La aplicación requiere un controlador jdbc tipo 2 para "IBM DB2 9.5". Por alguna extraña razón, el conector en Eclispe no pudo ver o usar las rutas en las variables de entorno de IBM DB2 para llegar a los archivos dll instalados en mi computadora portátil como el cliente jcc. El mensaje de error indicaba que no pudo encontrar el archivo dll db2jcct2 o no pudo encontrar las bibliotecas dependientes para ese archivo dll. Al final, eliminé el conector y lo reconstruí. Entonces funcionó correctamente. Estoy agregando esta solución aquí como documentación, porque no pude encontrar esta solución específica en ningún otro lugar.
fuente
La creación de una biblioteca estática funcionó para mí, compilando usando
g++ -static
. Incluye las bibliotecas dependientes junto con build.fuente
instalación de Microsoft Visual C ++ 2010 SP1 Redistributable Fix it
fuente
coloque los archivos DLL necesarios en la carpeta y establezca la ruta de la carpeta en la variable de entorno PATH. asegúrese de que se refleje la variable PATH del entorno actualizada.
fuente
Enfrentaba el mismo problema con la biblioteca ffmpeg después de fusionar dos proyectos de Android como un solo proyecto.
En realidad, el problema estaba llegando debido a dos versiones diferentes de la biblioteca ffmpeg, pero estaban cargadas con los mismos nombres en la memoria. Una biblioteca se colocó en JNiLibs mientras que otra estaba dentro de otra biblioteca utilizada como módulo. No pude modificar el código del módulo ya que era de solo lectura, así que cambié el nombre del que usé en mi propio código a ffmpegCamera y lo cargué en la memoria con el mismo nombre.
System.loadLibrary("ffmpegCamera");
Esto resolvió el problema y ahora ambas versiones de las bibliotecas se cargan bien con un nombre y un ID de proceso separados en la memoria.
fuente
Al llamar
System.loadLibrary()
, la JVM buscará en eljava.library.path
su biblioteca nativa. Sin embargo, si esa biblioteca nativa declara alguna dependencia en otras bibliotecas nativas, entonces el sistema operativo tendrá la tarea de encontrar esas dependencias de biblioteca nativa.Dado que el sistema operativo no tiene el concepto de
java.library.path
, no verá ningún directorio que coloque en java.library.path. En su lugar, solo buscará los directorios en la variable de entorno PATH del sistema operativo. Esto está totalmente bien si la dependencia de la biblioteca nativa es una biblioteca nativa del sistema operativo porque se encontrará en la RUTA. Sin embargo, si la dependencia de la biblioteca nativa es una biblioteca nativa que usted u otra persona creó, no se encontrará en la RUTA a menos que la coloque allí. Este comportamiento es extraño, inesperado y no está bien documentado, pero está documentado en el rastreador de problemas de OpenJDK aquí . También puede encontrar otra respuesta de StackOverflow que refuerce esta explicación, aquí .Entonces, tienes un par de opciones. Puede cargar cada biblioteca nativa en el orden de dependencia correcto usando
System.loadLibrary()
, o puede modificar la RUTA para incluir los directorios donde se almacenan sus bibliotecas nativas.fuente
Visual C++ Redistributable for VS2012
VSU_4\vcredist_x64.exe
oVSU_4\vcredist_x84.exe
dependiendo de la configuración de su sistemadll
archivos dentro de lalib
carpeta, junto con sus otras bibliotecas (por ejemplo\lib\win32-x86\your dll files
).fuente