Est -Djava.library.path =… équivalent à System.setProperty (“java.library.path”,…)

Je charge une bibliothèque externe placée dans ./lib . Ces deux solutions permettent-elles de définir l’équivalent de java.library.path?

  1. Définissez le chemin dans la console lors de l’exécution de jar:

     java -Djava.library.path=./lib -jar myApplication.jar 
  2. Définir le chemin dans le code avant de charger la bibliothèque:

     System.setProperty("java.library.path", "./lib"); 

Si elles sont équivalentes , pourquoi dans la deuxième solution, Java ne trouve-t-il pas la bibliothèque alors que la première est correcte?

Sinon, existe-t-il un moyen de définir le chemin dans le code?

En règle générale, les deux approches ont le même effet net: la propriété système java.library.path est définie sur la valeur ./lib .

Cependant , certaines propriétés système ne sont évaluées qu’à des moments spécifiques, tels que le démarrage de la machine virtuelle Java. Si java.library.path fait partie de ces propriétés (et que votre expérience semble l’indiquer), l’utilisation de la seconde approche n’aura aucun effet notable, sauf pour renvoyer la nouvelle valeur sur les getProperty() futurs de getProperty() .

En règle générale, l’utilisation de la propriété de ligne de commande -D fonctionne sur toutes les propriétés du système, tandis que System.setProperty() fonctionne uniquement sur les propriétés qui sont non seulement vérifiées au démarrage.

Bien que cela ne soit pas bien documenté, la propriété système java.library.path est une propriété “en lecture seule” en ce qui concerne la méthode System.loadLibrary() . Ceci est un bogue signalé mais il a été fermé par Sun par opposition à être corrigé. Le problème est que ClassLoader de la JVM lit cette propriété une fois au démarrage, puis la met en cache, ce qui ne nous permet pas de la modifier par la suite. La ligne System.setProperty("java.library.path", anyVal); n’aura aucun effet sauf pour les appels à la méthode System.getProperty() .

Heureusement, quelqu’un a posté une solution sur les forums Sun. Malheureusement, ce lien ne fonctionne plus mais j’ai trouvé le code sur une autre source . Voici le code que vous pouvez utiliser pour contourner le fait de ne pas pouvoir définir la propriété système java.library.path :

 public static void addDir(Ssortingng s) throws IOException { try { // This enables the java.library.path to be modified at runtime // From a Sun engineer at http://forums.sun.com/thread.jspa?threadID=707176 // Field field = ClassLoader.class.getDeclaredField("usr_paths"); field.setAccessible(true); Ssortingng[] paths = (Ssortingng[])field.get(null); for (int i = 0; i < paths.length; i++) { if (s.equals(paths[i])) { return; } } String[] tmp = new String[paths.length+1]; System.arraycopy(paths,0,tmp,0,paths.length); tmp[paths.length] = s; field.set(null,tmp); System.setProperty("java.library.path", System.getProperty("java.library.path") + File.pathSeparator + s); } catch (IllegalAccessException e) { throw new IOException("Failed to get permissions to set library path"); } catch (NoSuchFieldException e) { throw new IOException("Failed to get field handle to set library path"); } } 

AVERTISSEMENT: Cela peut ne pas fonctionner sur toutes les plates-formes et / ou JVM.

vous pouvez append trois lignes

  System.setProperty("java.library.path", "/path/to/libs" ); Field fieldSysPath = ClassLoader.class.getDeclaredField( "sys_paths" ); fieldSysPath.setAccessible( true ); fieldSysPath.set( null, null ); 

et aussi importer java.lang.reflect.Field C’est bon pour résoudre le problème