Go to Contents Go to Java Page
J2SE 1.5 虎の穴
 
 

環境変数 またの名を Deprecated からの復活

 
 
Tiger 環境変数はかつて参照できた
 
 

今回の話は環境変数に関してです。システムプロパティと間違えないでくださいね。

System クラスに getenv メソッドというのがあります。このメソッドは環境変数を取得するためのメソッドなのですが、実質的に使用することができませんでした。

ためしに次のようなコードを J2SE 1.4 でコンパイル、実行してみましょう。

サンプルのソース EnvironmentVariableTest1.java

このコードは環境変数 JAVA_HOME を取得して、出力するという単純なものです。

public class EnvironmentVariableTest1 {
    public static void main(String[] args) {
        String java_home = System.getenv("JAVA_HOME");
 	
        System.out.println("JAVA_HOME = " + java_home);
    }
}

これを J2SDK 1.4.2_04 でコンパイル、実行してみた結果は下のようになりました。

C:\examples>javac EnvironmentVariableTest1.java
注: EnvironmentVariableTest1.java は推奨されない API を使用またはオーバーライド
しています。
注: 詳細については、-deprecation オプションを指定して再コンパイルしてください。 C:\examples>java EnvironmentVariableTest1 Exception in thread "main" java.lang.Error: getenv no longer supported, use prop
erties and -D instead: JAVA_HOME
at java.lang.System.getenv(System.java:691)
at EnvironmentVariableTest1.main(EnvironmentVariableTest1.java:3) C:\examples>

この例から分かるように System#getenv メソッドは Deprecated であると同時に、実際に使ってみても例外が発生してしまって使えないことがわかります。

じゃ、なぜ getenv なんてメソッドがあったかというと、JDK 1.0 までは使えたからなのです!!!

そうだとすると、なんで Deprecated になったんでしょう。

答えはセキュリティのためなのです。

アプレットがローカルリソースを扱えないのと同じように、環境変数もローカルのリソースなので扱いを制限していたようです。でも、アプレットならいざ知らず、普通のアプリケーションだったら環境変数を扱ってもいいのになぁとずっと思っていました。

そこで Tiger です。

なんと Tiger では System.getenv の Deprecated がはずされました。JDK 1.0 の頃から Java を使っていますが、Deprecated だったメソッドが Deprecated をはずされたことなんてはじめてです。

これはすごいことですよ ^^;;

 

 
 
Tiger とりあえず使ってみる
 
 

さきほどの EnvironmentVariableTest1 クラスを Tiger でコンパイル、実行してみましょう。

C:\examples>javac EnvironmentVariableTest1.java
   
C:\examples>java EnvironmentVariableTest1
JAVA_HOME = C:\Program Files\Java\jdk1.5.0

C:\examples>

確かに正しい値が取得できていました。

Tiger ではすべての環境変数を取得するというメソッドも追加されています。

サンプルのソース EnvironmentVariableTest2.java

このサンプルはすべての環境変数を出力するというものです。引数なしの getenv メソッドはキー、値とも String の Map オブジェクトを返すので、それを 1 つ 1 つ出力しています。

import java.util.Map;
 
public class EnvironmentVariableTest2 {
    public static void main(String[] args) {
        Map<String, String> envs = System.getenv();
 
        for (Map.Entry<String, String> env: envs.entrySet()) {
            System.out.println(env);
        }
    }
}

実行すると、次のようになります。

C:\examples>java EnvironmentVariableTest2
PROCESSOR_ARCHITECTURE=x86
CG_BIN_PATH=C:\Program Files\NVIDIA Corporation\Cg\bin
LOGONSERVER=\\XXXXXX
HOMEDRIVE=C: ... 以下、省略 ...

 

 
 
Tiger 使うにはちょっと注意が
 
 

セキュリティの問題から Deprecated になったぐらいなので、やはりセキュリティは気になります。たとえば、次に示すサンプルを実行してみましょう。

サンプルのソース EnvironmentVariableTest3.java

 

public class EnvironmentVariableTest3 {
    public static void main(String[] args) {
        System.out.println("JAVA_HOME = " + System.getenv("JAVA_HOME"));
        System.out.println("USERNAME = " + System.getenv("USERNAME"));
    }
}

ただ実行するのでは能がないので、セキュリティマネージャを使って Sandbox の中で実行してみます。

C:\examples>java -Djava.security.manager EnvironmentVariableTest3
Exception in thread "main" java.security.AccessControlException: access denied (
java.lang.RuntimePermission getenv.JAVA_HOME)
at java.security.AccessControlContext.checkPermission(AccessControlConte
xt.java:264)
at java.security.AccessController.checkPermission(AccessController.java:
427)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:524)
at java.lang.System.getenv(System.java:794)
at EnvironmentVariableTest3.main(EnvironmentVariableTest3.java:3) C:\examples>

ありゃりゃ、例外が発生してしまいました。

Sandbox ではデフォルトで System#getenv メソッドは使えないようになっています。使用するにはポリシーを設定する必要があります。ポリシーは個々の環境変数単位で設定します。

設定は RuntimePermission を使用して行います。ターゲットネームは getenv.[環境変数名] です。

たとえば次に示すポリシーファイルを用意してみました。

grant { 
    permission java.lang.RuntimePermission "getenv.JAVA_HOME";
};

ポリシーファイルを指定して実行してみましょう。ポリシーファイル名は java.policy です。

C:\examples>java -Djava.security.manager -Djava.security.policy=java.policy Env
ironmentVariableTest3
JAVA_HOME = C:\Program Files\Java\jdk1.5.0
Exception in thread "main" java.security.AccessControlException: access denied (
java.lang.RuntimePermission getenv.JAVA_HOME)
at java.security.AccessControlContext.checkPermission(AccessControlConte
xt.java:264)
at java.security.AccessController.checkPermission(AccessController.java:
427)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:524)
at java.lang.System.getenv(System.java:794)
at EnvironmentVariableTest3.main(EnvironmentVariableTest3.java:4) C:\examples>

JAVA_HOME は取得できましたが、USERNAME は取得できず例外が発生します。それでは次のようにポリシーファイルを変更してみました。

grant { 
    permission java.lang.RuntimePermission "getenv.JAVA_HOME";
    permission java.lang.RuntimePermission "getenv.USERNAME";
};

これで実行すると、正しく値を取得できます。

C:\examples>java -Djava.security.manager  -Djava.security.policy=java.policy Env
ironmentVariableTest3              
JAVA_HOME = C:\Program Files\Java\jdk1.5.0
USERNAME = sakuraba C:\examples>

すべての環境変数を取得するようにするには、ポリシーファイルを次のようにします。

grant { 
    permission java.lang.RuntimePermission "getenv.*";
};

 

 
 
Tiger おわりに
 
 

環境変数が使えることはいいことなのですが、使い方には気をつけなくてはいけません。

たとえばプラットフォームによって大文字と小文字が区別されていなかったり、同じ情報を持つ環境変数の名前が異なったりします。マルチプラットフォームにするならば、こういうところに注意しなくてはならないですね。

それにしても、Deprecated からの復活というのはすごいことです。

 

今回使用したサンプルはここからダウンロードできます。

 

(Jun. 2004)

 
 
Go to Contents Go to Java Page