PARTE 1
Sto sviluppando un'applicazione Java che dovrebbe essere rilasciata come un jar. Questo programma dipende dalle librerie esterne C++ chiamate da JNI. Per caricare loro, io uso il metodo System.load
con un percorso assoluto e questo funziona benissimo.Java: caricamento delle DLL da un percorso relativo e nascosti all'interno di un jar
Tuttavia, ci tengo a "nascondere" al loro interno il JAR, così ho creato un pacchetto per raccoglierli. Questo mi obbliga a caricare un percorso relativo - il percorso del pacchetto. Con questo approccio, ho lasciato l'utente esegue il vaso in una qualsiasi directory, senza essere preoccupati per collegare le DLL o annoiato con un processo di installazione precedente.
Questo genera l'eccezione prevista:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Expecting an absolute path of the library
Come posso ottenere questo lavoro?
PARTE 2
L'approccio di copiare le DLL in una cartella (spiegato di seguito) funziona solo quando l'eseguo in ambiente Eclipse. L'esecuzione di un JAR esportato, i binari DLL sono ben realizzati, ma il caricamento di quello JNI lancia l'eccezione successiva:
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)
faccio funzionare questo metodo di caricamento:
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());
}
}
credo che questo potrebbe essere un problema privilegi di accesso , ma non so come risolverlo. Cosa ne pensi?
Perché vuoi nasconderli? –
Per fornire un barattolo pulito – supertreta