teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

別解を追加

2015/11/15 10:47

投稿

退会済みユーザー
answer CHANGED
@@ -3,4 +3,28 @@
3
3
  - ラッパーのメソッドはgetenv, setenv, setDebugMode
4
4
  - setDebugModeを呼んでいない場合、getenvはSystem.getenvを呼ぶ。setenvは空実装。
5
5
  - setDebugModeを呼んだ場合、getenvはsetenvされたキーに対応する値を返す。
6
- ラッパー及びスタブを実装/テストする手間は増えますが、テストコード自体の記述は楽になったと記憶しています。
6
+ ラッパー及びスタブを実装/テストする手間は増えますが、テストコード自体の記述は楽になったと記憶しています。
7
+ ---
8
+ 以下2015/11/15 19:45追記
9
+
10
+ サードベンダ製ライブラリが環境変数を参照する等の事情があるかと拝察します。
11
+ そうした場合、環境変数の参照がSystem.getenvによるか、Nativeコードによるかで対処が変わるかと考えます。理由はSystem.getenvが返す値は、ProcessEnvironmentがstatic finalに保持しているunmodifiableMapに格納されており、unmodifiableMapはvm起動時に初期化されているためです。
12
+
13
+ javaコードから参照する環境変数を変える場合は、前述の通りunmodifiableMapがstatic finalに保持されているため、リフレクションを使っても変更できず、親プロセスの段階でNativeプロセスの環境変数を変えておくしか手がないかと考えます。
14
+ Nativeコードから参照する環境変数を変える場合は、JNIやJNAでSetEnvironmentVariable(Win32)やsetenv(posix)を呼ぶことにより変更することができます。JNAで変更する場合のコード例は以下の通りです。
15
+ ```java
16
+ public class MyTest
17
+ public interface CLibrary extends Library {
18
+ CLibrary INSTANCE = (CLibrary)Native.loadLibrary("Kernel32.dll", CLibrary.class);
19
+ boolean SetEnvironmentVariableA(String name, String value);
20
+ }
21
+
22
+ public static void main(String[] args) {
23
+ try {
24
+ CLibrary.INSTANCE.SetEnvironmentVariableA("myEnv", "myValue");
25
+ } catch (Exception e) {
26
+ e.printStackTrace();
27
+ }
28
+ }
29
+ }
30
+ ```