2013-03-14 14 views
5

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

+0

http://stackoverflow.com/questions/2899804/setting-classpath-during-runt –

Odpowiedz

19

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); 
} 
+1

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

+0

Wymieniona klasa Field to: 'import java.lang.reflect.Field;' – Troyseph

+0

Java9 rejestruje "nielegalną operację dostępu odblaskowego". – Stefan