Czy w środowisku wykonawczym można dodać nową ścieżkę dla bibliotek natywnych? (Zamiast uruchamiania Java z właściwością java.library.path), więc wywołanie System.loadLibrary(nativeLibraryName)
będzie zawierało tę ścieżkę podczas próby znalezienia nativeLibraryName
. Czy to możliwe, czy te ścieżki zostały zamrożone po uruchomieniu JVM?Dodawanie nowych ścieżek dla bibliotek natywnych w środowisku wykonawczym w języku Java
Odpowiedz
Wydaje się niemożliwe bez małej hacking (czyli dostępu do prywatnych pól klasy ClassLoader)
Ten blog dostarczyć 2 sposoby to zrobić.
Dla przypomnienia, oto krótka wersja.
Wariant 1: w pełni zastąpić java.library.path z nowej wartości)
public static void setLibraryPath(String path) throws Exception {
System.setProperty("java.library.path", path);
//set sys_paths to null so that java.library.path will be reevalueted next time it is needed
final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
sysPathsField.setAccessible(true);
sysPathsField.set(null, null);
}
Opcja 2: dodać nową ścieżkę do bieżącego java.library.path
/**
* Adds the specified path to the java library path
*
* @param pathToAdd the path to add
* @throws Exception
*/
public static void addLibraryPath(String pathToAdd) throws Exception{
final Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths");
usrPathsField.setAccessible(true);
//get array of paths
final String[] paths = (String[])usrPathsField.get(null);
//check if the path to add is already present
for(String path : paths) {
if(path.equals(pathToAdd)) {
return;
}
}
//add the new path
final String[] newPaths = Arrays.copyOf(paths, paths.length + 1);
newPaths[newPaths.length-1] = pathToAdd;
usrPathsField.set(null, newPaths);
}
Rzeczywiście dość hack :) dzięki za umieszczenie go. To nie powinno być tak hacky, prawdopodobnie trudno jest zmienić tę ścieżkę ze względów bezpieczeństwa, nie jestem pewien. Będę tego unikać, ale miło jest wiedzieć, że istnieje. – Sergio
Wymieniona klasa Field to: 'import java.lang.reflect.Field;' – Troyseph
Java9 rejestruje "nielegalną operację dostępu odblaskowego". – Stefan
http://stackoverflow.com/questions/2899804/setting-classpath-during-runt –