Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set environment variables from Java?

How do I set environment variables from Java? I see that I can do this for subprocesses using ProcessBuilder. I have several subprocesses to start, though, so I'd rather modify the current process's environment and let the subprocesses inherit it.

There's a System.getenv(String) for getting a single environment variable. I can also get a Map of the complete set of environment variables with System.getenv(). But, calling put() on that Map throws an UnsupportedOperationException -- apparently they mean for the environment to be read only. And, there's no System.setenv().

So, is there any way to set environment variables in the currently running process? If so, how? If not, what's the rationale? (Is it because this is Java and therefore I shouldn't be doing evil nonportable obsolete things like touching my environment?) And if not, any good suggestions for managing the environment variable changes that I'm going to need to be feeding to several subprocesses?

like image 527
skiphoppy Avatar asked Nov 25 '08 17:11

skiphoppy


People also ask

Do I need to set environment variables in Java?

Before running Java programs on your machine you need to set two environment variables namely, PATH − The path environment variable is used to specify the set of directories which contains execution programs.

How do I set environment variables?

On the Windows taskbar, right-click the Windows icon and select System. In the Settings window, under Related Settings, click Advanced system settings. On the Advanced tab, click Environment Variables. Click New to create a new environment variable.

What environment variables should be set for Java path?

For Java applications, PATH must include the following directories: JDK's " bin " (binary) directory (e.g., " c:\Program Files\java\jdk1. x.x\bin "), which contains JDK programs such as Java Compiler " javac.exe " and Java Runtime " java.exe ".


1 Answers

For use in scenarios where you need to set specific environment values for unit tests, you might find the following hack useful. It will change the environment variables throughout the JVM (so make sure you reset any changes after your test), but will not alter your system environment.

I found that a combination of the two dirty hacks by Edward Campbell and anonymous works best, as one of the does not work under linux, one does not work under windows 7. So to get a multiplatform evil hack I combined them:

protected static void setEnv(Map<String, String> newenv) throws Exception {   try {     Class<?> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");     Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment");     theEnvironmentField.setAccessible(true);     Map<String, String> env = (Map<String, String>) theEnvironmentField.get(null);     env.putAll(newenv);     Field theCaseInsensitiveEnvironmentField = processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment");     theCaseInsensitiveEnvironmentField.setAccessible(true);     Map<String, String> cienv = (Map<String, String>)     theCaseInsensitiveEnvironmentField.get(null);     cienv.putAll(newenv);   } catch (NoSuchFieldException e) {     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);       }     }   } } 

This Works like a charm. Full credits to the two authors of these hacks.

like image 180
pushy Avatar answered Oct 18 '22 12:10

pushy