狠狠撸

狠狠撸Share a Scribd company logo
Java 设置环境变量


                     Zianed Hou
                    zianed@live.cn




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




Zianed                 Version 1.0   1
1、闯补惫补设置环境变量的需求说明

在 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
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
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
//输出结果如下:
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
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
= :/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、闯补惫补设置环境变量的实现


4.1 使用ProcessBuilder 进行设置

对子程序使用 ProcessBuilder 启用子程序进行设置环境变量,然后继承该子程
序即可实现子程序环境变量的设置。



Zianed                                        Version 1.0                                             7
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
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
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
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
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
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
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./xiaoxxcool/blog/item/ba8a31d046f0fdd9572c84d7.html
http://www.blogjava.net/chenlb/archive/2008/06/22/209957.html




Zianed                                     Version 1.0                                       14
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
Ad

Recommended

OSGi and Eclipse RCP
OSGi and Eclipse RCP
Eric Jain
?
Come configurare Liferay 6.0 per Oracle
Come configurare Liferay 6.0 per Oracle
Antonio Musarra
?
JPoint 2016 - Валеев Тагир - Странности Stream API
JPoint 2016 - Валеев Тагир - Странности Stream API
tvaleev
?
Owasp Indy Q2 2012 Advanced SQLi
Owasp Indy Q2 2012 Advanced SQLi
owaspindy
?
Down to Stack Traces, up from Heap Dumps
Down to Stack Traces, up from Heap Dumps
Andrei Pangin
?
Dpilot Source Code With ScreenShots
Dpilot Source Code With ScreenShots
DeepAnshu Sharma
?
Source Code for Dpilot
Source Code for Dpilot
Nidhi Chauhan
?
Debugging: Rules & Tools
Debugging: Rules & Tools
Ian Barber
?
#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG
Thierry Wasylczenko
?
Обзор фреймворка Twisted
Обзор фреймворка Twisted
Maxim Kulsha
?
ログ出力を改めて考える - JDK Flight Recorder の活用
ログ出力を改めて考える - JDK Flight Recorder の活用
Yoshiro Tokumasu
?
Hello click click boom
Hello click click boom
symbian_mgl
?
Innovative Specifications for Better Performance Logging and Monitoring
Innovative Specifications for Better Performance Logging and Monitoring
Cary Millsap
?
Lean React - Patterns for High Performance [ploneconf2017]
Lean React - Patterns for High Performance [ploneconf2017]
Devon Bernard
?
Deterministic simulation testing
Deterministic simulation testing
FoundationDB
?
PostgreSQL and PL/Java
PostgreSQL and PL/Java
Peter Eisentraut
?
code for quiz in my sql
code for quiz in my sql
JOYITAKUNDU1
?
Testing with Node.js
Testing with Node.js
Jonathan Waller
?
Flashback (Practical Test)
Flashback (Practical Test)
Anar Godjaev
?
Nantes Jug - Java 7
Nantes Jug - Java 7
Sébastien Prunier
?
Ejemplo radio
Ejemplo radio
lupe ga
?
Zabbix LLD from a C Module by Jan-Piet Mens
Zabbix LLD from a C Module by Jan-Piet Mens
NETWAYS
?
SCALE 15x Minimizing PostgreSQL Major Version Upgrade Downtime
SCALE 15x Minimizing PostgreSQL Major Version Upgrade Downtime
Jeff Frost
?
Using Fuzzy Code Search to Link Code Fragments in Discussions to Source Code
Using Fuzzy Code Search to Link Code Fragments in Discussions to Source Code
Nicolas Bettenburg
?
The Ring programming language version 1.7 book - Part 12 of 196
The Ring programming language version 1.7 book - Part 12 of 196
Mahmoud Samir Fayed
?
eROSE: Guiding programmers in Eclipse
eROSE: Guiding programmers in Eclipse
Thomas Zimmermann
?
Oracle试题Exam Adminv1.1
Oracle试题Exam Adminv1.1
Zianed Hou
?
翱谤补肠濒别的颁辞苍蝉迟谤补颈苍迟约束痴1.1
翱谤补肠濒别的颁辞苍蝉迟谤补颈苍迟约束痴1.1
Zianed Hou
?
闯补惫补中的贵濒辞补迟&补尘辫;顿辞耻产濒别以及滨别别别754研究痴1.0
闯补惫补中的贵濒辞补迟&补尘辫;顿辞耻产濒别以及滨别别别754研究痴1.0
Zianed Hou
?
础谤谤补测蝉的厂辞谤迟算法分析
础谤谤补测蝉的厂辞谤迟算法分析
Zianed Hou
?

More Related Content

What's hot (18)

#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG
Thierry Wasylczenko
?
Обзор фреймворка Twisted
Обзор фреймворка Twisted
Maxim Kulsha
?
ログ出力を改めて考える - JDK Flight Recorder の活用
ログ出力を改めて考える - JDK Flight Recorder の活用
Yoshiro Tokumasu
?
Hello click click boom
Hello click click boom
symbian_mgl
?
Innovative Specifications for Better Performance Logging and Monitoring
Innovative Specifications for Better Performance Logging and Monitoring
Cary Millsap
?
Lean React - Patterns for High Performance [ploneconf2017]
Lean React - Patterns for High Performance [ploneconf2017]
Devon Bernard
?
Deterministic simulation testing
Deterministic simulation testing
FoundationDB
?
PostgreSQL and PL/Java
PostgreSQL and PL/Java
Peter Eisentraut
?
code for quiz in my sql
code for quiz in my sql
JOYITAKUNDU1
?
Testing with Node.js
Testing with Node.js
Jonathan Waller
?
Flashback (Practical Test)
Flashback (Practical Test)
Anar Godjaev
?
Nantes Jug - Java 7
Nantes Jug - Java 7
Sébastien Prunier
?
Ejemplo radio
Ejemplo radio
lupe ga
?
Zabbix LLD from a C Module by Jan-Piet Mens
Zabbix LLD from a C Module by Jan-Piet Mens
NETWAYS
?
SCALE 15x Minimizing PostgreSQL Major Version Upgrade Downtime
SCALE 15x Minimizing PostgreSQL Major Version Upgrade Downtime
Jeff Frost
?
Using Fuzzy Code Search to Link Code Fragments in Discussions to Source Code
Using Fuzzy Code Search to Link Code Fragments in Discussions to Source Code
Nicolas Bettenburg
?
The Ring programming language version 1.7 book - Part 12 of 196
The Ring programming language version 1.7 book - Part 12 of 196
Mahmoud Samir Fayed
?
eROSE: Guiding programmers in Eclipse
eROSE: Guiding programmers in Eclipse
Thomas Zimmermann
?
Обзор фреймворка Twisted
Обзор фреймворка Twisted
Maxim Kulsha
?
ログ出力を改めて考える - JDK Flight Recorder の活用
ログ出力を改めて考える - JDK Flight Recorder の活用
Yoshiro Tokumasu
?
Hello click click boom
Hello click click boom
symbian_mgl
?
Innovative Specifications for Better Performance Logging and Monitoring
Innovative Specifications for Better Performance Logging and Monitoring
Cary Millsap
?
Lean React - Patterns for High Performance [ploneconf2017]
Lean React - Patterns for High Performance [ploneconf2017]
Devon Bernard
?
Deterministic simulation testing
Deterministic simulation testing
FoundationDB
?
code for quiz in my sql
code for quiz in my sql
JOYITAKUNDU1
?
Flashback (Practical Test)
Flashback (Practical Test)
Anar Godjaev
?
Ejemplo radio
Ejemplo radio
lupe ga
?
Zabbix LLD from a C Module by Jan-Piet Mens
Zabbix LLD from a C Module by Jan-Piet Mens
NETWAYS
?
SCALE 15x Minimizing PostgreSQL Major Version Upgrade Downtime
SCALE 15x Minimizing PostgreSQL Major Version Upgrade Downtime
Jeff Frost
?
Using Fuzzy Code Search to Link Code Fragments in Discussions to Source Code
Using Fuzzy Code Search to Link Code Fragments in Discussions to Source Code
Nicolas Bettenburg
?
The Ring programming language version 1.7 book - Part 12 of 196
The Ring programming language version 1.7 book - Part 12 of 196
Mahmoud Samir Fayed
?
eROSE: Guiding programmers in Eclipse
eROSE: Guiding programmers in Eclipse
Thomas Zimmermann
?

Viewers also liked (7)

Oracle试题Exam Adminv1.1
Oracle试题Exam Adminv1.1
Zianed Hou
?
翱谤补肠濒别的颁辞苍蝉迟谤补颈苍迟约束痴1.1
翱谤补肠濒别的颁辞苍蝉迟谤补颈苍迟约束痴1.1
Zianed Hou
?
闯补惫补中的贵濒辞补迟&补尘辫;顿辞耻产濒别以及滨别别别754研究痴1.0
闯补惫补中的贵濒辞补迟&补尘辫;顿辞耻产濒别以及滨别别别754研究痴1.0
Zianed Hou
?
础谤谤补测蝉的厂辞谤迟算法分析
础谤谤补测蝉的厂辞谤迟算法分析
Zianed Hou
?
闯惫尘的最小使用内存测试
闯惫尘的最小使用内存测试
Zianed Hou
?
翱谤补肠濒别中厂辩濒解析过程
翱谤补肠濒别中厂辩濒解析过程
Zianed Hou
?
翱谤补肠濒别数据库日志满导致错误
翱谤补肠濒别数据库日志满导致错误
Zianed Hou
?
Oracle试题Exam Adminv1.1
Oracle试题Exam Adminv1.1
Zianed Hou
?
翱谤补肠濒别的颁辞苍蝉迟谤补颈苍迟约束痴1.1
翱谤补肠濒别的颁辞苍蝉迟谤补颈苍迟约束痴1.1
Zianed Hou
?
闯补惫补中的贵濒辞补迟&补尘辫;顿辞耻产濒别以及滨别别别754研究痴1.0
闯补惫补中的贵濒辞补迟&补尘辫;顿辞耻产濒别以及滨别别别754研究痴1.0
Zianed Hou
?
础谤谤补测蝉的厂辞谤迟算法分析
础谤谤补测蝉的厂辞谤迟算法分析
Zianed Hou
?
闯惫尘的最小使用内存测试
闯惫尘的最小使用内存测试
Zianed Hou
?
翱谤补肠濒别中厂辩濒解析过程
翱谤补肠濒别中厂辩濒解析过程
Zianed Hou
?
翱谤补肠濒别数据库日志满导致错误
翱谤补肠濒别数据库日志满导致错误
Zianed Hou
?
Ad

Recently uploaded (20)

Creating Inclusive Digital Learning with AI: A Smarter, Fairer Future
Creating Inclusive Digital Learning with AI: A Smarter, Fairer Future
Impelsys Inc.
?
Mastering AI Workflows with FME - Peak of Data & AI 2025
Mastering AI Workflows with FME - Peak of Data & AI 2025
Safe Software
?
No-Code Workflows for CAD & 3D Data: Scaling AI-Driven Infrastructure
No-Code Workflows for CAD & 3D Data: Scaling AI-Driven Infrastructure
Safe Software
?
High Availability On-Premises FME Flow.pdf
High Availability On-Premises FME Flow.pdf
Safe Software
?
TrustArc Webinar - 2025 Global Privacy Survey
TrustArc Webinar - 2025 Global Privacy Survey
TrustArc
?
Supporting the NextGen 911 Digital Transformation with FME
Supporting the NextGen 911 Digital Transformation with FME
Safe Software
?
“Addressing Evolving AI Model Challenges Through Memory and Storage,” a Prese...
“Addressing Evolving AI Model Challenges Through Memory and Storage,” a Prese...
Edge AI and Vision Alliance
?
FME for Good: Integrating Multiple Data Sources with APIs to Support Local Ch...
FME for Good: Integrating Multiple Data Sources with APIs to Support Local Ch...
Safe Software
?
FME for Distribution & Transmission Integrity Management Program (DIMP & TIMP)
FME for Distribution & Transmission Integrity Management Program (DIMP & TIMP)
Safe Software
?
OWASP Barcelona 2025 Threat Model Library
OWASP Barcelona 2025 Threat Model Library
PetraVukmirovic
?
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance
?
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
caoyixuan2019
?
FIDO Seminar: New Data: Passkey Adoption in the Workforce.pptx
FIDO Seminar: New Data: Passkey Adoption in the Workforce.pptx
FIDO Alliance
?
Security Tips for Enterprise Azure Solutions
Security Tips for Enterprise Azure Solutions
Michele Leroux Bustamante
?
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Alliance
?
Providing an OGC API Processes REST Interface for FME Flow
Providing an OGC API Processes REST Interface for FME Flow
Safe Software
?
FIDO Seminar: Evolving Landscape of Post-Quantum Cryptography.pptx
FIDO Seminar: Evolving Landscape of Post-Quantum Cryptography.pptx
FIDO Alliance
?
AI vs Human Writing: Can You Tell the Difference?
AI vs Human Writing: Can You Tell the Difference?
Shashi Sathyanarayana, Ph.D
?
AI VIDEO MAGAZINE - June 2025 - r/aivideo
AI VIDEO MAGAZINE - June 2025 - r/aivideo
1pcity Studios, Inc
?
AudGram Review: Build Visually Appealing, AI-Enhanced Audiograms to Engage Yo...
AudGram Review: Build Visually Appealing, AI-Enhanced Audiograms to Engage Yo...
SOFTTECHHUB
?
Creating Inclusive Digital Learning with AI: A Smarter, Fairer Future
Creating Inclusive Digital Learning with AI: A Smarter, Fairer Future
Impelsys Inc.
?
Mastering AI Workflows with FME - Peak of Data & AI 2025
Mastering AI Workflows with FME - Peak of Data & AI 2025
Safe Software
?
No-Code Workflows for CAD & 3D Data: Scaling AI-Driven Infrastructure
No-Code Workflows for CAD & 3D Data: Scaling AI-Driven Infrastructure
Safe Software
?
High Availability On-Premises FME Flow.pdf
High Availability On-Premises FME Flow.pdf
Safe Software
?
TrustArc Webinar - 2025 Global Privacy Survey
TrustArc Webinar - 2025 Global Privacy Survey
TrustArc
?
Supporting the NextGen 911 Digital Transformation with FME
Supporting the NextGen 911 Digital Transformation with FME
Safe Software
?
“Addressing Evolving AI Model Challenges Through Memory and Storage,” a Prese...
“Addressing Evolving AI Model Challenges Through Memory and Storage,” a Prese...
Edge AI and Vision Alliance
?
FME for Good: Integrating Multiple Data Sources with APIs to Support Local Ch...
FME for Good: Integrating Multiple Data Sources with APIs to Support Local Ch...
Safe Software
?
FME for Distribution & Transmission Integrity Management Program (DIMP & TIMP)
FME for Distribution & Transmission Integrity Management Program (DIMP & TIMP)
Safe Software
?
OWASP Barcelona 2025 Threat Model Library
OWASP Barcelona 2025 Threat Model Library
PetraVukmirovic
?
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance
?
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
caoyixuan2019
?
FIDO Seminar: New Data: Passkey Adoption in the Workforce.pptx
FIDO Seminar: New Data: Passkey Adoption in the Workforce.pptx
FIDO Alliance
?
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Alliance
?
Providing an OGC API Processes REST Interface for FME Flow
Providing an OGC API Processes REST Interface for FME Flow
Safe Software
?
FIDO Seminar: Evolving Landscape of Post-Quantum Cryptography.pptx
FIDO Seminar: Evolving Landscape of Post-Quantum Cryptography.pptx
FIDO Alliance
?
AI VIDEO MAGAZINE - June 2025 - r/aivideo
AI VIDEO MAGAZINE - June 2025 - r/aivideo
1pcity Studios, Inc
?
AudGram Review: Build Visually Appealing, AI-Enhanced Audiograms to Engage Yo...
AudGram Review: Build Visually Appealing, AI-Enhanced Audiograms to Engage Yo...
SOFTTECHHUB
?
Ad

闯补惫补设置环境变量

  • 1. Java 设置环境变量 Zianed Hou zianed@live.cn 1、闯补惫补设置环境变量的需求说明 2、Java获取环境变量 2.1 Java获取输出环境变量 2.2 Win下查看环境变量 2.3 Solaris10 下查看环境变量 3、Java环境变量实现机制的分析 4、闯补惫补设置环境变量的实现 4.1 使用ProcessBuilder 进行设置 4.2 直接使用新的环境变量组代替原先的 4.3 使用java执行期间的-D参数 4.4 在Runtime.exec中调用实现 4.5 使用JNI调用本地接口实现 Zianed Version 1.0 1
  • 2. 1、闯补惫补设置环境变量的需求说明 在 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. 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. 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. //输出结果如下: 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. 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. = :/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、闯补惫补设置环境变量的实现 4.1 使用ProcessBuilder 进行设置 对子程序使用 ProcessBuilder 启用子程序进行设置环境变量,然后继承该子程 序即可实现子程序环境变量的设置。 Zianed Version 1.0 7
  • 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. 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. 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. 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. 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. 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. 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./xiaoxxcool/blog/item/ba8a31d046f0fdd9572c84d7.html http://www.blogjava.net/chenlb/archive/2008/06/22/209957.html Zianed Version 1.0 14