PARTE 1
Estoy desarrollando una aplicación Java que se debe lanzar como un contenedor. Este programa depende de librerías externas de C++ llamadas por JNI. Para cargarlos, utilizo el método System.load
con una ruta absoluta y esto funciona bien.Java - Cargando dlls por una ruta relativa y ocultarlos dentro de un contenedor
Sin embargo, realmente quiero "esconderlos" dentro del JAR, así que he creado un paquete para recogerlos. Esto me obliga a cargar una ruta relativa: la ruta del paquete. Con este enfoque, dejo que el usuario ejecute el JAR en cualquier directorio, sin preocuparse por vincular los archivos DLL o aburrido con un proceso de instalación anterior.
Esto produce la excepción prevista:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Expecting an absolute path of the library
¿Cómo puedo conseguir este trabajo?
PARTE 2
El enfoque de copiar los archivos DLL en una carpeta (explicado más adelante) sólo funciona cuando lo ejecuto en el entorno Eclipse. Ejecución de un JAR exportados, los binarios DLL están bien creados, pero la carga de la JNI lanza la siguiente excepción:
Exception in thread "main" java.lang.reflect.InvocationTargetException
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:56) Caused by: java.lang.UnsatisfiedLinkError: C:\Users\Supertreta\Desktop\nm files\temp\jniBin.dll: Can't find dependent libraries at java.lang.ClassLoader$NativeLibrary.load(Native Method)
corro este método de carga:
public static void loadBinaries(){
String os = System.getProperty("os.name").toLowerCase();
if(os.indexOf("win") >= 0){
ArrayList<String> bins = new ArrayList<String>(){{
add("/nm/metadata/bin/dependence1.dll");
add("/nm/metadata/bin/dependence2.dll");
add("/nm/metadata/bin/dependence3.dll");
add("/nm/metadata/bin/dependence4.dll");
add("/nm/metadata/bin/jniBin.dll");
}};
File f = null;
for(String bin : bins){
InputStream in = FileManager.class.getResourceAsStream(bin);
byte[] buffer = new byte[1024];
int read = -1;
try {
String[] temp = bin.split("/");
f = new File(TEMP_FOLDER, temp[temp.length-1]);
FileOutputStream fos = new FileOutputStream(f);
while((read = in.read(buffer)) != -1) {
fos.write(buffer, 0, read);
}
fos.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.load(f.getAbsolutePath());
}
}
Creo que esto podría ser un problema privilegios de acceso , pero no sé cómo resolverlo ¿Qué piensas?
¿Por qué quieres para ocultarlos? –
Para proporcionar un recipiente limpio – supertreta