Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Java设置环境变量

6,767 views

Published on

1、Java设置环境变量的需求说明
2、Java获取环境变量
2.1 Java获取输出环境变量
2.2 Win下查看环境变量
2.3 Solaris10下查看环境变量
3、Java环境变量实现机制的分析
4、Java设置环境变量的实现
4.1 使用ProcessBuilder 进行设置
4.2 直接使用新的环境变量组代替原先的
4.3 使用java执行期间的-D参数
4.4 在Runtime.exec中调用实现
4.5 使用JNI调用本地接口实现

Published in: Technology, News & Politics
  • Be the first to comment

Java设置环境变量

  1. 1. Java 设置环境变量 Zianed Hou zianed@live.cn 1、Java设置环境变量的需求说明 2、Java获取环境变量 2.1 Java获取输出环境变量 2.2 Win下查看环境变量 2.3 Solaris10 下查看环境变量 3、Java环境变量实现机制的分析 4、Java设置环境变量的实现 4.1 使用ProcessBuilder 进行设置 4.2 直接使用新的环境变量组代替原先的 4.3 使用java执行期间的-D参数 4.4 在Runtime.exec中调用实现 4.5 使用JNI调用本地接口实现 Zianed Version 1.0 1
  2. 2. 1、Java设置环境变量的需求说明 在 Java 中只提供了 System.getenv()获取环境变量的方法,并没有提供动态的设置 环境变量的。 有时根据程序的需要需要动态的设置环境变量中的值以备使用。 当调用设置环境变量时: import java.util.Map; public class Env { public static void main(String[] args) { Map<String, String> env = System.getenv(); System.out.println("Env:"); for (Map.Entry<String, String> envEntry : env.entrySet()) { System.out.println(envEntry.getKey() + " = " + envEntry.getValue()); } System.out.println("..."); env.put("zianed", "linary"); System.out.println(System.getenv("zianed")); } } 将抛出如下异常: Exception in thread "main" java.lang.UnsupportedOperationException at java.util.Collections$UnmodifiableMap.put(Collections.java:1285) at net.unixcenter.zianed.test.Env.main(Env.java:16) 使用示例如下: 在用户登录后将用户名和密码放置在环境变量中供其他程序的使用。 2、Java获取环境变量 获取对应的已经设置的环境变量的值 Zianed Version 1.0 2
  3. 3. public static String getenv(String name) { SecurityManager sm = getSecurityManager(); if (sm != null) { sm.checkPermission(new RuntimePermission("getenv."+name)); } return ProcessEnvironment.getenv(name); } 获取全部的环境变量 public static java.util.Map<String,String> getenv() { SecurityManager sm = getSecurityManager(); if (sm != null) { sm.checkPermission(new RuntimePermission("getenv.*")); } return ProcessEnvironment.getenv(); } 2.1 Java获取输出环境变量 //Env.java import java.util.Map; public class Env { public static void main(String[] args) { Map<String, String> env = System.getenv(); System.out.println("Env:"); for (Map.Entry<String, String> envEntry : env.entrySet()) { System.out.println(envEntry.getKey() + " = " + envEntry.getValue()); } System.out.println("..."); } } Zianed Version 1.0 3
  4. 4. 2.2 Win下查看环境变量 C:Documents and SettingsZianed>set ALLUSERSPROFILE=C:Documents and SettingsAll Users ANT_HOME=D:apache-ant-1.7.1 APPDATA=C:Documents and SettingsZianedApplication Data ClassPath=C:Program FilesJavajdk1.6.0_10lib;D:apache-ant-1.7.1lib;. CLIENTNAME=Console CommonProgramFiles=C:Program FilesCommon Files COMPUTERNAME=ZIANED ComSpec=C:WINDOWSsystem32cmd.exe FP_NO_HOST_CHECK=NO HOMEDRIVE=C: HOMEPATH=Documents and SettingsZianed JAVA_HOME=C:Program FilesJavajdk1.6.0_10 LOGONSERVER=ZIANED NUMBER_OF_PROCESSORS=2 OS=Windows_NT Path=C:Program FilesCommon FilesNetSarang;C:Program FilesJavajdk1.6.0_10b in;C:WINDOWSsystem32;C:WINDOWS;C:WINDOWSSystem32Wbem;C:Program FilesATI TechnologiesATI.ACECore-Static;C:Program FilesCommon FilesThunder NetworkK anKanCodecs;C:Program FilesQuickTimeQTSystem;D:apache-ant-1.7.1bin;D:pro gramoracle920bin; PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH PROCESSOR_ARCHITECTURE=x86 PROCESSOR_IDENTIFIER=x86 Family 15 Model 6 Stepping 5, GenuineIntel PROCESSOR_LEVEL=15 PROCESSOR_REVISION=0605 ProgramFiles=C:Program Files PROMPT=$P$G QTJAVA=C:Program FilesJavajre6libextQTJava.zip SESSIONNAME=Console SystemDrive=C: SystemRoot=C:WINDOWS TEMP=C:DOCUME~1ZianedLOCALS~1Temp TMP=C:DOCUME~1ZianedLOCALS~1Temp USERDOMAIN=ZIANED USERNAME=Zianed USERPROFILE=C:Documents and SettingsZianed windir=C:WINDOWS C:Documents and SettingsZianed> Zianed Version 1.0 4
  5. 5. //输出结果如下: Env: USERPROFILE = C:Documents and SettingsZianed PATHEXT = .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH JAVA_HOME = C:Program FilesJavajdk1.6.0_10 TEMP = C:DOCUME~1ZianedLOCALS~1Temp SystemDrive = C: ProgramFiles = C:Program Files Path = C:Program FilesCommon FilesNetSarang;C:Program FilesJavajdk1.6.0_10bin;C:WINDOWSsystem32;C:WINDOWS;C:WINDOWS System32Wbem;C:Program FilesATI TechnologiesATI.ACECore-Static;C:Program FilesCommon FilesThunder NetworkKanKanCodecs;C:Program FilesQuickTimeQTSystem;D:apache-ant-1.7.1bin;D:programoracle92 0bin; HOMEDRIVE = C: PROCESSOR_REVISION = 0605 CLIENTNAME = Console USERDOMAIN = ZIANED QTJAVA = C:Program FilesJavajre6libextQTJava.zip ALLUSERSPROFILE = C:Documents and SettingsAll Users PROCESSOR_IDENTIFIER = x86 Family 15 Model 6 Stepping 5, GenuineIntel ClassPath = C:Program FilesJavajdk1.6.0_10lib;D:apache-ant-1.7.1lib;. SESSIONNAME = Console TMP = C:DOCUME~1ZianedLOCALS~1Temp CommonProgramFiles = C:Program FilesCommon Files =:: = :: LOGONSERVER = ZIANED PROCESSOR_ARCHITECTURE = x86 FP_NO_HOST_CHECK = NO OS = Windows_NT HOMEPATH = Documents and SettingsZianed PROCESSOR_LEVEL = 15 ANT_HOME = D:apache-ant-1.7.1 COMPUTERNAME = ZIANED windir = C:WINDOWS SystemRoot = C:WINDOWS NUMBER_OF_PROCESSORS = 2 USERNAME = Zianed ComSpec = C:WINDOWSsystem32cmd.exe APPDATA = C:Documents and SettingsZianedApplication Data ... Zianed Version 1.0 5
  6. 6. 2.3 Solaris10 下查看环境变量 root@test-177-ce0 # bash root@test-177-ce0 # env MANPATH=:/usr/man:/usr/share/man:/opt/SUNWvts/man:/opt/SUNWexplo/man:/opt/SUNWsnee p/man:/opt/CTEact/man SHELL=/sbin/sh TERM=xterm SSH_CLIENT=192.168.1.27 2077 22 SSH_TTY=/dev/pts/1 USER=root LD_LIBRARY_PATH=/usr/openwin/lib OPENWINHOME=/usr/openwin MAIL=/var/mail//root PATH=/bin:/usr/local/bin _=/bin/env PWD=/ EDITOR=vi LANG=zh_CN.GBK TZ=PRC PS1=root@test-177-ce0 # PS2=root@test-177-ce0 > HOME=/ SHLVL=2 LOGNAME=root SSH_CONNECTION=192.168.1.27 2077 192.168.1.177 22 root@test-177-ce0 # 输出结果如下: root@test-177-ce0 # ls Env.java Env.java root@test-177-ce0 # javac Env.java root@test-177-ce0 # java Env Env: XFILESEARCHPATH = /usr/dt/app-defaults/%L/Dt LANG = zh_CN.GBK PWD = / SSH_TTY = /dev/pts/1 _ = /bin/java SHLVL = 1 OPENWINHOME = /usr/openwin NLSPATH = /usr/dt/lib/nls/msg/%L/%N.cat MANPATH Zianed Version 1.0 6
  7. 7. = :/usr/man:/usr/share/man:/opt/SUNWvts/man:/opt/SUNWexplo/man:/opt/SUNWsneep/man:/opt /CTEact/man USER = root SSH_CLIENT = 192.168.1.27 2077 22 MAIL = /var/mail//root EDITOR = vi TZ = PRC PS2 = root@test-177-ce0 > HOME = / PS1 = root@test-177-ce0 # LD_LIBRARY_PATH = /usr/jdk/instances/jdk1.5.0/jre/lib/sparc/server:/usr/jdk/instances/jdk1.5.0/jre/lib/sparc:/usr/jdk/inst ances/jdk1.5.0/jre/../lib/sparc:/usr/openwin/lib SSH_CONNECTION = 192.168.1.27 2077 192.168.1.177 22 TERM = xterm SHELL = /sbin/sh PATH = /bin:/usr/local/bin LOGNAME = root ... 3、Java环境变量实现机制的分析 根据源代码的分析,可以发现 getenv 方法调用的是: ProcessEnvironment.getenv(name);方法 查看其源代码发现如下: final class ProcessEnvironment extends HashMap<String,String> 可见其本质是一个 HashMap 的键值对。 4、Java设置环境变量的实现 4.1 使用ProcessBuilder 进行设置 对子程序使用 ProcessBuilder 启用子程序进行设置环境变量,然后继承该子程 序即可实现子程序环境变量的设置。 Zianed Version 1.0 7
  8. 8. public class Env { public static void main(String[] args) { ProcessBuilder pb = new ProcessBuilder(); pb.command("set hello=world; "); Map<String, String> map = pb.environment(); map.put("zianed", "linary"); Map<String, String> env = pb.environment(); System.out.println(env.get("zianed")); } } 4.2 直接使用新的环境变量组代替原先的 //MapEnv.java import java.lang.reflect.Field; import java.util.Collections; import java.util.HashMap; import java.util.Map; public class MapEnv { public static void main(String[] args) { System.out.println("$zianed=" + System.getenv("zianed")); Map<String, String> envMap = new HashMap<String, String>(); envMap.put("zianed", "zianed"); try { setEnv(envMap); } catch (Exception e) { System.out.println("出错啦"); e.printStackTrace(); } System.out.println("$zianed=" + System.getenv("zianed")); } @SuppressWarnings("unchecked") public static void setEnv(Map<String, String> newenv) throws Zianed Version 1.0 8
  9. 9. Exception { 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); break; } } } } 输出如下: $zianed=null $zianed=null 可见此种方法并没有进行实质性的改变。 4.3 使用java执行期间的-D参数 java -cp <classpath> -Dkey1=value -Dkey2=value ... // ChangeProperty.java public class ChangeProperty { public static void main(String[] args) { System.out.println("Property$zianed=" + System.getProperty("zianed")); System.out.println("Env$zianed=" + System.getenv("zianed")); } } 测试如下 E:ZianedDesktopexercisejni>javac ChangeProperty.java Zianed Version 1.0 9
  10. 10. E:ZianedDesktopexercisejni>java -Dzianed=zianed ChangeProperty Property$zianed=zianed Env$zianed=Zianed -D 参数的一个巧妙使用 java 命令引入 jar 时可以-cp 参数, 但时-cp 不能用通配符(多个 jar 时什么 烦要一个个写,不能*.jar),面通常的 jar 都在同一目录,且多于 1 个。前些日 子找到(发现)-Djava.ext.dirs 太好。 java -Djava.ext.dirs=lib MyClass 4.4 在Runtime.exec中调用实现 And if you're innocent some other process passed it on to its child process, just like you did in your Runtime.exec() call. // RunTimeSetEnv.java import java.io.IOException; public class RunTimeSetEnv { public static void main(String[] args) { System.out.println("$zianed=" + System.getenv("zianed")); try { Runtime.getRuntime().exec("cmd set zianed=zianed"); } catch (IOException e) { e.printStackTrace(); } System.out.println("$zianed=" + System.getenv("zianed")); } } 输出如下: $zianed=null $zianed=null 可见是没有办法进行跨进程持久化的。 4.5 使用JNI调用本地接口实现 使用 C/CPP 编写本地接口语言文件设置环境变量,通过 JNI 调用实现。 Zianed Version 1.0 10
  11. 11. 1)编写调用的函数,生成 C 头文件 //ChangeEnv.java public class ChangeEnv { static { try{ System.loadLibrary("changeEnv");//声明欲加载的动态链接库 } catch(UnsatisfiedLinkError e ){ System.err.println("Can not load library "+e.toString()); } } public native void setEnv(String name ,String value, int replace);//声明一个本地调用接口 } 生成本地头文件 D:Microsoft Visual StudioMyProjectsChangeEnvDebug>javac ChangeEnv.java D:Microsoft Visual StudioMyProjectsChangeEnvDebug>javah ChangeEnv 2)编写相关 C 代码实现功能 //Change.cpp #include "ChangeEnv.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <dos.h> JNIEXPORT void JNICALL Java_ChangeEnv_setEnv(JNIEnv * env,jobject obj,jstring name,jstring value,jint replace){ if(replace==0)//如果 replace==0 表示不发生置换,直接退出 return ; ////从 instring 字符串取得指向字符串 UTF 编码的指针 const char * name_char =(const char *) env->GetStringUTFChars(name ,JNI_FALSE); const char * value_char =(const char *) env->GetStringUTFChars(value ,JNI_FALSE); //实际调用的 C 库函数,把环境变量写成 key=value 格式 char * key_value=(char *)name_char; printf("1--------n"); printf("C$CLASSPATH=%sn",getenv("CLASSPATH")); strcat(key_value, "="); strcat(key_value, value_char); printf("C$%sn",key_value); putenv(key_value); printf("1--------n"); printf("C$CLASSPATH=%sn",getenv("CLASSPATH")); Zianed Version 1.0 11
  12. 12. printf("2--------n"); putenv("zianed=zianed"); printf("C$zianed=%sn",getenv("zianed")); //通知虚拟机本地代码不再需要通过 name_char 访问 Java 字符串,否则会 //造成内存泄露 env->ReleaseStringUTFChars(name,(const char *)name_char); env->ReleaseStringUTFChars(value,(const char *)value_char); printf("Hello Dynamic Link Library has been calling!n"); return ; } 编译的时间需要引入%JAVA_HOME%/include 和%JAVA_HOME%/include/win32 两个 头文件。然后将 dll 文件拷贝至工程中即可。 在 Unix/Linux 中,是要编译产生.so 文件 // ChangeEnv.cpp #include "ChangeEnv.h" #include <stdio.h> #include <stdlib.h> JNIEXPORT void JNICALL Java_ChangeEnv_setEnv(JNIEnv * env,jobject obj,jstring name,jstring value,jint replace){ const char * name_chr = (const char *)env->GetStringUTFChars(name,JNI_FALSE); const char * value_chr = (const char *)env->GetStringUTFChars(value,JNI_FALSE); setenv(name_chr,value_chr,replace); env->ReleaseStringUTFChars(name,(const char *)name_chr); env->ReleaseStringUTFChars(value,(const char *)value_chr); return ; } root@test-177-ce0 # gcc -fpic -c -I /usr/java/include -I /usr/java/include/solaris ChangeEnv.cpp root@test-177-ce0 # ls -l ./ ×ÜÊý 12 -rw-r--r-- 1 root root 746 1Ô 2ÈÕ 14:45 ChangeEnv.class -rw-r--r-- 1 root root 508 1Ô 2ÈÕ 15:19 ChangeEnv.cpp -rw-r--r-- 1 root root 435 1Ô 2ÈÕ 14:46 ChangeEnv.h -rw-r--r-- 1 root root 314 1Ô 2ÈÕ 14:44 ChangeEnv.java -rw-r--r-- 1 root root 1592 1Ô 2ÈÕ 15:19 ChangeEnv.o root@test-177-ce0 # gcc -G -o libchangeEnv.so ChangeEnv.o Zianed Version 1.0 12
  13. 13. root@test-177-ce0 # ls -l ./ ×ÜÊý 26 -rw-r--r-- 1 root root 746 1Ô 2ÈÕ 14:45 ChangeEnv.class -rw-r--r-- 1 root root 508 1Ô 2ÈÕ 15:19 ChangeEnv.cpp -rw-r--r-- 1 root root 435 1Ô 2ÈÕ 14:46 ChangeEnv.h -rw-r--r-- 1 root root 314 1Ô 2ÈÕ 14:44 ChangeEnv.java -rw-r--r-- 1 root root 1592 1Ô 2ÈÕ 15:19 ChangeEnv.o -rwxr-xr-x 1 root root 6932 1Ô 2ÈÕ 15:21 libchangeEnv.so 其中的 libChangeEnv.so 就是所需要的 C 库文件。 3)测试运行 // TestChangeEnv.java import java.io.InputStreamReader; import java.io.LineNumberReader; public class TestChangeEnv { public static void main(String[] args) { String pathPer = System.getProperty("java.library.path"); pathPer+=":."; System.setProperty("java.library.path",pathPer);//把当前目录加到动态链接库路径中 System.out.println("Java$ClassPath="+System.getenv("ClassPath"));//打印改变之前的 PATH 路径 ChangeEnv changePath = new ChangeEnv ();//生成一个 ChangeEnv 对象 changePath.setEnv("ClassPath","%ClassPath%;C:",1); System.out.println("Java$ClassPath="+System.getenv("ClassPath"));//打印改变之后的 PATH 路径 } } D:Microsoft Visual StudioMyProjectsChangeEnvDebug>java TestChangeEnv Java$ClassPath=C:Program FilesJavajdk1.6.0_10lib;D:apache-ant-1.7.1lib;. 1-------- C$CLASSPATH=C:Program FilesJavajdk1.6.0_10lib;D:apache-ant-1.7.1lib;. C$ClassPath=%ClassPath%;C: 1-------- C$CLASSPATH=%ClassPath%;C: 2-------- C$zianed=zianed Zianed Version 1.0 13
  14. 14. Hello Dynamic Link Library has been calling! Java$ClassPath=C:Program FilesJavajdk1.6.0_10lib;D:apache-ant-1.7.1lib;. D:Microsoft Visual StudioMyProjectsChangeEnvDebug> References http://stackoverflow.com/questions/318239/how-do-i-set-environment-variables-from-java http://www.developer.com/java/other/article.php/626151/Global-Variables-in-Java-with-the-Single ton-Pattern.htm http://bytes.com/topic/java/answers/782644-set-environment-variable-java http://www.theserverside.com/news/thread.tss?thread_id=43397 http://hi.baidu.com/xiaoxxcool/blog/item/ba8a31d046f0fdd9572c84d7.html http://www.blogjava.net/chenlb/archive/2008/06/22/209957.html Zianed Version 1.0 14
  15. 15. Zianed Homepage:http://my.unix-center.net/~Zianed/ Mail: hxuanzhe86@sina.com MSN:zianed@live.cn QQ:1196123432 QQGroup: 50457022 Date:2010-1-6 Zianed Version 1.0 15

×