Est-il possible de définir une variable d'environnement au moment de l'exécution à partir d'une application Java? Dans la classe Java 1.5 Java.lang.System, il existe une méthode getenv (); je n'aurais besoin que d'une méthode setenv () ...
Est-il possible de modifier les variables d'environnement dans le processus Java lui-même? pas dans le processus enfant.
Est-il possible d'y parvenir grâce à JNI? Et comment cela fonctionnerait-il?
Merci.
EDIT: .__ Ok. Permettez-moi de formuler les choses comme suit: pouvons-nous faire ce qui suit avec Java? Répondre s'il vous plaît.
Hemal Pandya a répondu: "Vous pouvez modifier l'environnement des processus en cours et des processus enfants, mais pas du processus parent qui a généré ce processus." Es-tu d'accord avec ça ?
Si mon intuition est correcte et que vous souhaitez réellement modifier l'environnement au profit d'un sous-processus spawned (forked) (Runtime.getRuntime().exec()
), utilisez ProcessBuilder au lieu de exec()
. Vous pouvez créer un environnement personnalisé via la méthode environment () de votre instance ProcessBuilder
.
Si c’est pas ce que vous essayez d’atteindre, veuillez ignorer cette réponse.
METTRE À JOUR
La réponse à vos trois questions spécifiques mises à jour est la suivante:
System.getenv()
dans la même machine virtuelle, ou les deux.setenv
ou son équivalent spécifique à la plate-forme via JNI. Vous pouvez également utiliser la méthode extrêmement compliquée de point 2 ci-dessous, qui fonctionne pour tout processus (à condition que vous disposiez des autorisations). Sachez toutefois que dans la plupart des machines virtuelles, cette modification peut ne jamais être reflétée dans les valeurs renvoyées par System.getenv()
. , car l’environnement est le plus souvent mis en cache au démarrage de la machine virtuelle dans un Java.util.Map
(ou l’équivalent).System.Java
dans la distribution que vous utiliserez pour le déploiement de la machine virtuelle Java), vous pouvez essayer de pirater l'implémentation (via l'ordre de chargement des classes, réflexion)). ou (instrumentation } _.) Dans le cas de la machine virtuelle Java v1.6 de Sun, par exemple, le cache d'environnement est géré par la classe non documentée ProcessEnvironment
(que vous pouvez corriger).gdb
sera suspendu pour une durée différente de zéro.ProcessBuilder
lors de la génération du processus.Notez que toutes les méthodes ci-dessus, à l'exception de celle impliquant ProcessBuilder
, sont fragiles, sujettes aux erreurs, non portables à des degrés divers et sujettes aux conditions de concurrence dans des environnements multithreads.
En réponse à votre question mise à jour:
setenv()
ou autre chose. Cependant, vous n’avez probablement pas besoin de le faire et cela peut ne pas fonctionner dans toutes les situations.ProcessBuilder
.Vous pouvez obtenir un descripteur de la carte sous-jacente sur laquelle ProcessEnvironment se tient, puis mettre de nouvelles choses et supprimer toutes celles que vous voulez.
Cela fonctionne sur Java 1.8.0_144. Je ne peux pas garantir que cela fonctionne sur n'importe quelle version de Java, mais c'est probablement similaire si vous devez vraiment changer l'environnement au moment de l'exécution.
private static Map<String,String> getModifiableEnvironment() throws Exception{
Class pe = Class.forName("Java.lang.ProcessEnvironment");
Method getenv = pe.getDeclaredMethod("getenv");
getenv.setAccessible(true);
Object unmodifiableEnvironment = getenv.invoke(null);
Class map = Class.forName("Java.util.Collections$UnmodifiableMap");
Field m = map.getDeclaredField("m");
m.setAccessible(true);
return (Map) m.get(unmodifiableEnvironment);
}
Après avoir obtenu la référence à la carte, ajoutez ce que vous voulez et récupérez-la à l'aide de l'ancien appel System.getenv ("") habituel.
J'ai essayé cela fonctionne dans MAC ne fonctionne pas dans Windows dans les deux versions Java Java 1.8_161
Je ne pense pas, du moins pas uniquement en Java, mais pourquoi avez-vous besoin de faire cela? En Java, il est préférable d’utiliser des propriétés via System.getProperties()
, que vous pouvez modifier.
Si vous en aviez vraiment besoin, je suis sûr que vous pourriez insérer la fonction C setenv
dans un appel JNI. En fait, je ne serais pas surpris que quelqu'un l'ait déjà fait. Je ne connais pas les détails du code, cependant.
Vous pouvez modifier l'environnement des processus en cours et des processus enfants, mais pas du processus parent ayant généré ce processus.