Cómo arreglar un UnsatisfiedLinkError (no Puede encontrar las bibliotecas dependientes) en un proyecto de JNI

StackOverflow https://stackoverflow.com/questions/6092200

Pregunta

Estoy trabajando en un proyecto Java que utiliza la JNI.La JNI llamadas de una biblioteca personalizada que he escrito yo mismo, vamos a decir mylib.dll y que depende de la 3ª parte de la biblioteca, libsndfile-1.dll.

Cuando ejecuto mi programa se bloquea con

java.lang.UnsatisfiedLinkError:  C:\...path...\mylib.dll: Can't find dependent libraries.

He buscado en este sitio (y los demás) y he intentado una serie de correcciones:

  1. Corrí dependency walker.DW dio un par de advertencias -- que dos librerías requeridas por libsndfile, MPR.DLL y SHLWAPI.DLL había sin resolver "las importaciones", pero la DW FAQ dijo que estas advertencias podría ser ignorado.

  2. He arreglado los nombres de método en mylib.dll, como se sugiere aquí.El método de los nombres de alguna manera, había conseguido alterados por el compilador, pero he añadido del enlazador y el método de dll ahora nombres coinciden con los de mi jni archivo de encabezado exactamente.

  3. Pongo todos estos archivos Dll en el mismo directorio, el mismo directorio que el .tarro que los llama, para asegurar que los que estamos en el CAMINO correcto.

No dice.

¿Alguien tiene alguna idea de lo que está pasando?

Yo estoy haciendo mi desarrollo en Visual Studio 2010 en un MacBook pro (a través de Parallels).Yo estoy haciendo mis pruebas en Windows XP en un portátil toshiba.

¿Fue útil?

Solución

Estoy bastante seguro de que la ruta de clases y la biblioteca compartida de la ruta de búsqueda tienen poco que ver el uno con el otro.De acuerdo a La JNI Libro (que por cierto es de edad), en Windows si no utiliza el java.library.path la propiedad del sistema, el archivo DLL debe estar en el directorio de trabajo actual o en un directorio que aparece en el Windows PATH la variable de entorno.


Actualización:

Parece que Oracle ha eliminado el PDF desde su página web.He actualizado el enlace de arriba para señalar un ejemplo de los PDF que viven en la Universidad de Texas en Arlington.

Además, también se puede leer de Oracle versión HTML de la JNI Especificación.Que vive en el Java 8 de la sección de la página web de Java, así que espero que va a estar allí por un tiempo.


Actualización 2:

Al menos en Java 8 (no he revisado las versiones anteriores) se puede hacer:

java -XshowSettings:properties -version

para encontrar la biblioteca compartida de la ruta de búsqueda.Busque el valor de la java.library.path propiedad en esa salida.

Otros consejos

Quiero informar este caso interesante, 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 lo es.Luego, utilizo Walker de dependency y que se encuentra en Windows XP, no hay tiempo de ejecución de VC ++ como mi requerimiento DLL.Después de instalar el paquete de tiempo de ejecución de VC ++ aquí funciona como un encanto.Lo que me molestó es que sigue diciendo que no puede encontrar bibliotecas dependientes, mientras que de manera intuitiva la DLL dependiente de JNI está allí, sin embargo, finalmente resulta que la DLL dependiente de JNI requiere otro DL dependiente.Espero que esto ayude.

Necesitas cargar tu biblioteca JNI.

sistema.loadlibrary carga el DLL dela ruta JVM (Ruta del contenedor JDK).

Si desea cargar un archivo explícito con una ruta, use Sistema.carga ()

Consulte también: Diferencia entre System.load () ySystem.loadlibrary en Java

Verifique que su ruta de la biblioteca sea correcta o no.Por supuesto, puede usar el siguiente código para verificar la ruta de la ruta de la biblioteca: System.out.println(System.getProperty("java.library.path"));

Puede designar el java.library.path al iniciar una aplicación Java:

java -Djava.library.path=path ...

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.

¿Tienen idéntico problema con en el equipo con XP, cuando la instalación de javacv y opencv en combinación con Eclipse.Resultó que yo era faltan los siguientes archivos:

  • msvcp100.dll
  • msvcr100.dll

Una vez que estos se han instalado, el proyecto compilado y funcionaba bien.

  • Respuesta corta: para el error "No se puede encontrar la biblioteca dependiente", verifique su ruta $ (corresponde al punto de bala # 3 a continuación)
  • respuesta larga:
    1. Pure Java World: JVM usa "classpath" para encontrar archivos de clase
    2. JNI World (Java / Límite nativo): JVM usa "java.library.path" (que por defecto en $ ruta) para encontrar DLLS
    3. Mundo nativo puro: el código nativo usa $ ruta para cargar otras DLLs

Encontré un gran artículo de algunos amigos en Keepsafe que pasó por lo mismo que hice.¡Funcionó para mí, así que espero que te ayude también!Tenga una lectura si está interesado ( Los peligros de la carga de bibliotecas nativas en Android ) o simplemente usar

compile 'com.getkeepsafe.relinker:relinker:1.2.3'

y reemplazar

System.loadLibrary("myLibrary");

con

ReLinker.loadLibrary(context, "mylibrary");

Solía tener exactamente el mismo problema, y finalmente se resolvió.

Puse todas las DLL dependientes en la misma carpeta donde se almacenó MyLib.dll y asegurarme de que el compilador de Java pudiera encontrarlo (si no hay myLib.dll en la ruta de compilación, habría un error que informa esto durante la compilación).Lo importante que necesita para notar es que debe asegurarse de que todas las libs dependientes sean de la misma versión con mylib.dll, por ejemplo, si su versión de lanzamiento mylib.dll también debe colocar la versión de lanzamiento de todas sus libs dependientes..

Espero que esto pueda ayudar a otros que hayan encontrado el mismo problema.

Tuve el mismo problema, y probé todo lo que se publica aquí para solucionarlo, pero ninguno funcionó para mí. En mi caso, estoy usando Cygwin para compilar la DLL.Parece que JVM intenta encontrar las DLL de JRE en el camino virtual de Cygwin. Añadí la ruta del directorio virtual de Cygwin a las DLL de Jre y funciona ahora. Hice algo como:

Set Ruta="/ cygdrive / c / archivos de programa / java / jdk1.8.0_45";% ruta%

En mi situación, estaba tratando de ejecutar un servicio web de Java en Tomcat 7 a través de un conector en Eclipse.La aplicación corrió bien cuando implementé el archivo de guerra a una instancia de Tomcat 7 en mi computadora portátil.La aplicación requiere un controlador de tipo 2 JDBC para "IBM DB2 9.5".Para alguna razón extraña, el conector en Eclispe no pudo ver ni usar las rutas en las variables de entorno IBM DB2, para llegar a los archivos DLL instalados en mi computadora portátil como el cliente JCC.El mensaje de error declaró que no pudo encontrar el archivo DB2JCCT2 DLL o no pudo encontrar las bibliotecas dependientes para ese archivo DLL.En última instancia, eliminé el conector y la reconstruí.Luego 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.

Creación de biblioteca estática funcionó para mí, compilando usando g++ -static.Paquete las bibliotecas dependientes junto con la construcción.

Instalación de Microsoft Visual C ++ 2010 SP1 Redistribuible lo arreglado

Coloque las DLL requeridas en la carpeta y configure la ruta de la carpeta en la variable de entorno de ruta. Asegúrese de que se refleje la variable de ruta de entorno actualizada.

Me enfrenté el mismo problema con la biblioteca FFMPEG después de fusionar dos proyectos de Android como un proyecto.

En realidad, el problema llegó debido a dos versiones diferentes de la biblioteca FFMPEG, pero se cargaron con los mismos nombres en la memoria.Se colocó una biblioteca en Jnilibs, mientras que otro estaba dentro de otra biblioteca utilizada como módulo.No pude modificar el código de módulo, ya que fue readonal, así que renombra el nombre que se usa en mi propio código a ffmpegcamera y lo cargó en la memoria con el mismo nombre.

System.loadLibrary("ffmpegCamera");

Esto resolvió el problema y ahora ambas versiones de bibliotecas se están cargando bien como nombre y identificación de procesos separados en la memoria.

  1. Ir a http://tess4j.sourceforge.net/usage.html y haga clic en Visual C++ Redistributable for VS2012
  2. Descargar y ejecutar VSU_4\vcredist_x64.exe o VSU_4\vcredist_x84.exe dependiendo de la configuración de su sistema
  3. Pon tu dll los archivos dentro de la lib carpeta, junto con el resto de las bibliotecas (por ejemplo, \lib\win32-x86\your dll files).
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top