Javaから環境変数を設定するにはどうすればいいですか?サブプロセスでこれを行うには、ProcessBuilder
ただし、開始するサブプロセスがいくつかあるため、現在のプロセスの環境を変更し、サブプロセスにそれを継承させる方がよいでしょう。
単一の環境変数を取得するためのがあります。 また、を使用して環境変数の完全なセットSystem.getenv(String)
を取得することもできます。 しかし、を呼び出すと がスローされます。どうやら、環境を読み取り専用にすることを意味しているようです。 また、 はありません。Map
System.getenv()
put()
Map
UnsupportedOperationException
System.setenv()
では、現在実行中のプロセスで環境変数を設定する方法はありますか? ある場合、その方法は? そうでない場合、その理由は何ですか? (これは Java なので、環境に触れるような悪質で移植性のない古いことを行うべきではないからでしょうか?) また、そうでない場合、複数のサブプロセスに供給する必要がある環境変数の変更を管理するための良い提案はありますか?
ベストアンサー1
ユニット テスト用に特定の環境値を設定する必要があるシナリオで使用する場合は、次のハックが役立つ場合があります。これにより、JVM 全体の環境変数が変更されますが (テスト後に変更を必ずリセットしてください)、システム環境は変更されません。
Edward Campbell と匿名の 2 人のダーティ ハックを組み合わせると最も効果的であることがわかりました。1 つは Linux では動作せず、もう 1 つは Windows 7 では動作しないためです。そこで、マルチプラットフォームの悪質なハックを作成するために、これらを組み合わせました。
protected static void setEnv(Map<String, String> newenv) throws Exception {
try {
Class<?> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment");
theEnvironmentField.setAccessible(true);
Map<String, String> env = (Map<String, String>) theEnvironmentField.get(null);
env.putAll(newenv);
Field theCaseInsensitiveEnvironmentField = processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment");
theCaseInsensitiveEnvironmentField.setAccessible(true);
Map<String, String> cienv = (Map<String, String>) theCaseInsensitiveEnvironmentField.get(null);
cienv.putAll(newenv);
} catch (NoSuchFieldException e) {
Class[] classes = Collections.class.getDeclaredClasses();
Map<String, String> env = System.getenv();
for(Class cl : classes) {
if("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
Object obj = field.get(env);
Map<String, String> map = (Map<String, String>) obj;
map.clear();
map.putAll(newenv);
}
}
}
}
これは見事に機能します。これらのハックの 2 人の作者に全面的に謝意を表します。