web-dev-qa-db-fra.com

Puis-je savoir à quelle variable Java.library.path correspond sur la plate-forme actuelle?

Jusqu'à présent, j'ai appris ce qui suit sur la propriété Java.library.path:

  • Il est utilisé lors du chargement de bibliothèques natives, contrairement aux classes Java
  • Sa valeur par défaut dépend du système d'exploitation:
    • Sous Windows, il est mappé sur PATH
    • Sous Linux, il correspond à LD_LIBRARY_PATH
    • Sous OS X, il est mappé sur DYLD_LIBRARY_PATH

(Veuillez me corriger si j'ai mal compris ce qui précède)

Ma motivation:

Je souhaite modifier la valeur de Java.library.path vue par une application Java à partir du cadre que j'ai configuré pour appeler l'application Java. I vous voulez le faire non pas en définissant directement la propriété Java.library.path, mais plutôt en modifiant la variable de chemin d'accès système à laquelle elle correspond. Je voudrais une manière propre de le faire sans code laid spécifique au système d'exploitation ou laisser de côté les cas Edge si possible.

Ma question:

Existe-t-il un moyen de demander à l'implémentation locale Java à quelle variable d'environnement Java.library.path correspond?

Ensuite, dans un script Shell, je serais en mesure d'écrire quelque chose comme:

path_var = get_library_path_variable  # the magic function I want to call
${path_var} = /my/custom/path:${${path_var}}
26
Charlie

Ce n'est pas une question totalement déraisonnable, mais il n'y a pas de bonne réponse, donc pour la postérité, je vais essayer d'expliquer pourquoi vous êtes coincé, et pourquoi cela ne fonctionnera pas.

  1. Java.library.path n'est pas garanti d'être défini à partir d'une variable d'environnement. Vous pouvez spécifier ce que vous voulez que ce soit avec -Djava.library.path=. Plus que probablement, c'est ce que vous vraiment voulez faire de toute façon. C'est pourquoi l'option existe.

  2. Il s'avère (sur Windows au moins), que la variable d'environnement que vous recherchez n'est pas seulement utilisée sans problème. Essayez ce code.

    package com.stackoverflow;
    
    import Java.util.Map;
    
    public class LibPathFinder {
        public static void main(String[] args) {
            String javaLibPath = System.getProperty("Java.library.path");
            Map<String, String> envVars = System.getenv();
            System.out.println(envVars.get("Path"));
            System.out.println(javaLibPath);
            for (String var : envVars.keySet()) {
                System.err.println("examining " + var);
                if (envVars.get(var).equals(javaLibPath)) {
                    System.out.println(var);
                }
            }
        }
    }
    

    Vous remarquerez que lorsqu'il s'exécute, les deux premières choses qu'il imprime sont différentes. Si Java utilise la variable windows PATH, il joue d'abord avec la valeur. J'ai renoncé à rechercher ce qui se passait. Le fait était qu'il n'y avait pas de variable d'environnement qui correspondait exactement au Java.library.path. Je n'ai pas essayé sous Linux ou OSX, votre kilométrage peut varier

  3. Ce n'est vraiment pas très agréable de jouer avec les variables d'environnement de quelqu'un comme ça. Ils sont utilisés pour l'ensemble du Shell, vous engagez donc vos utilisateurs à avoir votre bibliothèque partagée sur leur environnement, mais seulement parfois. La seule vraie raison de changer Java.library.path consiste à ajouter des bibliothèques natives. Si vous utilisez des bibliothèques natives, vous avez déjà du code spécifique au système d'exploitation (il doit être compilé pour la plate-forme, n'est-ce pas?), Vous avez donc vraiment déjà abandonné la lutte pour "aucun cas Edge spécifique à la plate-forme". La meilleure chose à faire est de placer votre bibliothèque native dans un endroit où le chemin du système (quel qu'il soit) le trouvera déjà, ou d'y ajouter le chemin de votre bibliothèque en permanence avec un programme d'installation quelconque . Si vous ne voulez faire aucune de ces choses, je vous suggère d'utiliser une variante du code de @ malat, en imprimant le vrai Java.library.path, puis en ajoutant votre chemin d'accès à ce résultat dans votre script, puis utilisez le -D option pour le définir pour l'exécution réelle du programme.

16
Ian McLaird

Sur ma box Linux, voici ce que je ferais:

$ cat GetSystemProperty.Java
import Java.util.Properties;
import Java.util.Enumeration;

public class GetSystemProperty {
  public static void main(String args[]) {
    if( args.length == 0 ) {
      Properties p = System.getProperties();
      Enumeration keys = p.keys();
      while (keys.hasMoreElements()) {
        String key = (String)keys.nextElement();
        String value = (String)p.get(key);
        System.out.println(key + " : " + value);
      }
    }
    else {
      for (String key: args) {
        System.out.println(System.getProperty( key ));
      }
    }
  }
}
$ javac GetSystemProperty.Java
$ Java GetSystemProperty Java.library.path
/usr/lib/jvm/Java-6-openjdk/jre/lib/AMD64/server:/usr/lib/jvm/Java-6-openjdk/jre/lib/AMD64:/usr/lib/jvm/Java-6-openjdk/jre/../lib/AMD64:/usr/Java/packages/lib/AMD64:/usr/lib/jni:/lib:/usr/lib
10
malat