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?
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.
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.
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 ".
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With