如何从Java设置环境变量?我发现我可以使用ProcessBuilder。不过,我有几个子流程要启动,所以我宁愿修改当前流程的环境,让子流程继承它
有一个System.getenv(String)用于获取单个环境变量。我还可以使用System.getenv()获得环境变量整套的映射。但是,在Map上调用put()会抛出一个不支持的操作异常——显然,这意味着环境是只读的。而且,没有System.setenv()
那么,有没有办法在当前运行的进程中设置环境变量?如果是,怎么做?如果没有,理由是什么?(这是因为这是Java,因此我不应该做不可移植的过时的事情,比如触摸我的环境吗?)如果不是,有什么好的建议来管理环境变量的变化,我需要将这些变化反馈给几个子流程
对于需要为单元测试设置特定环境值的场景,您可能会发现以下hack很有用。它将在整个JVM中更改环境变量(因此请确保在测试后重置任何更改),但不会更改系统环境
我发现Edward Campbell和anonymous的两个肮脏的黑客组合效果最好,因为其中一个在linux下不工作,另一个在windows 7下不工作。所以为了得到一个多平台的邪恶黑客,我将它们结合起来:
受保护的静态void setEnv(Map<;String,String>;newenv)引发异常{
试一试{
Class<;?>;ProcessEnvironment Class=Class.forName(“java.lang.ProcessEnvironment”);
Field theEnvironment Field=processEnvironmentClass.getDeclaredField(“theEnvironment”);
环境字段。设置为可访问(true);
Map<;String,String>;env=(Map<;String,String>;)环境字段。get(null);
环境保护局(新环境);
字段theCaseInsensitiveEnvironmentField=processEnvironmentClass.getDeclaredField(“theCaseInsensitiveEnvironment”);
CaseInsensitiveEnvironmentField.setAccessible(true);
Map<;String,String>;cienv=(Map<;String,String>;)caseinsensitiveenvironmentfield.get(null);
cienv.putAll(新环境);
}捕获(无此字段例外){
Class[]classes=Collections.Class.getDeclaredClasses();
Map<;String,String>;env=System.getenv();
对于(类别cl:类别){
if(“java.util.Collections$UnmodifiableMap”.equals(cl.getName())){
字段字段=cl.getDeclaredField(“m”);
字段。setAccessible(true);
Object obj=field.get(env);
映射<;字符串,字符串>;映射=(映射<;字符串,字符串>;)对象;
map.clear();
普塔尔地图(新环境);
}
}
}
}
这很有魅力。完全归功于这两位黑客的作者