実行時に環境変数をJava application?から設定できますか?Java 1.5 Java.lang.Systemクラスにはgetenv()メソッドがあります。 setenv()メソッドのみが必要です...
Javaプロセス自体で、子プロセスではなく、環境変数を変更することは可能ですか?.
JNIで達成することは可能ですか?そして、それはどのように機能しますか?
ありがとう。
編集:Okこのように言えば-Javaで次のことができます。答えてください。
Hemal Pandyaは、「現在のプロセスと子プロセスの環境は変更できますが、このプロセスを生成した親プロセスの環境は変更できません」と回答しています。これに同意しますか?
私の直感が正しい場合、実際に環境を変更して、生成された(分岐した)サブプロセスのために環境を変更したい場合(Runtime.getRuntime().exec()
)、exec()
の代わりに ProcessBuilder を使用します。 ProcessBuilder
インスタンスの environment() メソッドを使用して、カスタム環境を構築できます。
これがnotである場合は、この回答を無視してください。
[〜#〜] update [〜#〜]
更新された3つの具体的な質問に対する回答は次のとおりです。
System.getenv()
によって返される値を変更するか、またはその両方を変更するかによって異なります。setenv
またはそのプラットフォーム固有の同等物をJNI経由で呼び出すことができます。また、以下のpoint 2)から非常に複雑な方法を使用することもできます。これは、任意のプロセスで機能します(権限がある場合)。ただし、ほとんどのJVMでは、環境は_Java.util.Map
_(または同等のもの)での仮想マシンの起動時にキャッシュされないことが多いため、この変更がSystem.getenv()
によって返される値に決して反映されないことに注意してください。System.Java
_のソースコードを参照)、実装のハッキングを試みることができます(クラスの読み込み順序を介して、 reflection 、または instrumentation 。)たとえば、Sunのv1.6 JVMの場合、環境キャッシュは文書化されていないProcessEnvironment
クラス(これはパッチを適用できます。)gdb
によってインスツルメントされたプロセスはゼロ以外の量で中断されるため、これはパフォーマンスを低下させます時間。ProcessBuilder
を介して。ProcessBuilder
を含むメソッドを除く上記のすべてのメソッドは、脆弱で、エラーが発生しやすく、さまざまな程度に移植できず、マルチスレッド環境で競合状態になりやすいことに注意してください。
更新された質問に対する回答:
setenv()
または何かを呼び出す場合。ただし、おそらくこれを行う必要はなく、すべての状況で機能するとは限りません。ProcessBuilder
を使用。ProcessEnvironmentが保持している基礎となるマップのハンドルを取得し、新しいものを入れて必要なものをすべて削除できます。
これはJava 1.8.0_144で動作します。Javaの他のバージョンで動作することを保証できませんが、実行時に環境を本当に変更する必要がある場合はおそらく同様です。
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);
}
マップへの参照を取得したら、必要なものを追加するだけで、通常の古いSystem.getenv( "")呼び出しを使用してマップを取得できます。
Os Java version 1.8_161の両方でWindowsで動作しないMACで動作するようにこれを試しました
少なくともJavaの場合はそうではありませんが、なぜそうする必要があるのでしょうか? Javaでは、変更可能なSystem.getProperties()
を介してプロパティを使用することをお勧めします。
本当に必要な場合は、C setenv
関数をJNI呼び出しでラップできると確信しています。実際、誰かが既にそうしていても驚かないでしょう。ただし、コードの詳細はわかりません。
現在のプロセスと子プロセスの環境を変更できますが、このプロセスを生成した親プロセスの環境は変更できません。