2009-07-06 18 views
14

Estoy ejecutando una biblioteca a través de JNI (no lo escribí), e internamente llama a otra DLL. Me sale un error que dice "No puedo encontrar bibliotecas dependientes" a menos que ponga la ruta de la otra DLL en la variable PATH del sistema (estoy en Windows XP). Me gustaría poder manejar esto en la línea de comandos de java, y ya he intentado agregarlo a -Djava.library.path y al classpath, ninguno de los cuales funcionó (esperaba que -Djava.library.path funcionara pero no classpath, pero ninguno funcionó). ¿Hay alguna forma de hacer esto?Bibliotecas dependientes de JNI

gracias,

Jeff

Respuesta

18
  • Si usted tiene un nombre DLL 'MyNativeDLL.dll', entonces debería usar 'MyNativeDLL' en su llamada LoadLibrary.
  • Dependency Walker uso para comprobar si hay archivos requeridos por MyNativeDLL.dll
  • Si los hay, los incluyen en la misma carpeta que MyNativeDLL.dll - que se obtiene se trate de trabajar poniendo los archivos necesarios adicionales en la carpeta System32.
+0

que funcionaría, pero me gustaría que los archivos DLL dependientes estén en la carpeta que deseen y luego solo haga referencia a esa carpeta. ¿es eso posible? –

+0

tuvimos una situación similar en la que tuvimos que cargar OurJNI.dll y OurNative.dll utilizando la llamada LoadLibrary. De nuevo, importa el orden en que se cargan. No pudimos encontrar ninguna otra forma de hacer esto. – Vivek

+2

Right - bienvenido a DLL hell. En nuestro caso, solo estoy cargando A.dll que internamente hace referencia a B.dll para que B siempre se cargue después de A. Solo estaba tratando de evitar modificar la variable PATH. –

5

Pude hacer que esto funcionara sin poner ningún DLL en la RUTA usando System.load() en todas las DLL en orden de dependencia inverso. Para que quede claro, estaba llamando a System.load() en todas las DLL dependientes, no solo en las DLL JNI. No tiene que llamar a System.load() en las DLL que vienen con Windows (están en la RUTA).

Estaba haciendo esto en una aplicación web donde un frasco incluía los archivos DLL que se estaban desempaquetando. Tu situación parece más simple, así que creo que debería funcionar. En general, seguí la solución aquí: How to make a JAR file that includes DLL files?

0

He inyectado con éxito una carpeta en la variable PATH utilizando JNA. Esto se puede utilizar como una solución alternativa si desea implementar sus DLL dependientes junto con su aplicación sin contaminar el entorno global o interferir con el orden de carga DLL explícito.

Sin embargo, no me queda claro cómo afecta el ciclo de vida del cargador de clases. Solo he probado esta técnica en el sistema de módulos NetBeans, pero si miras el código de clase de ClassLoader para loadLibrary, verás que almacena en caché algunas variables de ruta. Puede o no ser necesario crear un nuevo cargador de clases para cargar la biblioteca.

El inconveniente es que necesita utilizar JNA o JNI. Además, parece un truco bastante grave. Consulte here para ver un ejemplo de cómo establecer una variable de entorno utilizando JNA.

2

Esto me ayudó mucho. también logró cargar un archivo DLL JNI construido usando cygwin:

primera:

/* conditioned if OS is windows because also need it to work in Linux env. */ 
System.loadLibrary("cygwin1"); 

a continuación:

System.loadLibrary("mylib"); 

En las ventanas, esto requiere ya sea estableciendo el java.library.path para que coincida con las dos bibliotecas ubicaciones.

Si se ejecuta desde Eclipse, esta configuración se puede reemplazar por "Ubicación de bibliotecas nativas" en la ruta de compilación de Java (en la configuración de las bibliotecas de JRE).

Sin embargo, sigue siendo un poco complicado.