Is it possible to set an environment variable at runtime from a Java application? In Java 1.5 java.lang.System class there is the getenv() method, I would only need a setenv() method...
Is it possible to modify the environment variables in the java process itself; not in the child process.
Is it possible to achieve it through JNI? And how would that work?
Thanks.
EDIT: Ok let me put it this way - Can we do the following with Java. Please answer.
Hemal Pandya has answered that "You can modify the environment of current and child processes but not of the parent process that spawned this process." Do you agree with this ?
Env vars are intentionally private to each process. So unless the program provides an API for changing its env vars you can't modify them once the program is running.
Using runtime environment variables. Runtime environment variables are key/value pairs deployed alongside a function. These variables are scoped to the function and are not visible to other functions in your project.
If you're using the installer we'll do this part for you. If you installed the Java Development Kit (JDK) you'll be setting the JAVA_HOME environment variable. If you installed the Java Runtime Environment (JRE) you will follow the same steps but set the JRE_HOME environment variable instead.
If my intuition is correct, and you actually want to modify the environment for the benefit of a spawned (forked) sub-process (Runtime.getRuntime().exec()
), then use ProcessBuilder instead of exec()
. You can build a custom environment via your ProcessBuilder
instance's environment() method.
If this is not what you are trying to achieve then kindly disregard this answer.
UPDATE
The answer to your three updated, specific questions is as follows:
System.getenv()
in the same JVM, or both.setenv
or its platform-specific equivalent via JNI. You may also employ the extremely convoluted method from point 2 below, which works for any process (provided you have the permissions.) However, be aware that in most JVMs this change might never be reflected in the values returned by System.getenv()
, as the environment is more often than not cached at virtual machine startup in a java.util.Map
(or equivalent.)System.java
in whichever JVM distribution you will be using to deploy), you may try hacking the implementation (via class loading order, reflection, or instrumentation.) In the case of SUN's v1.6 JVM, for example, the environment cache is managed by the undocumented ProcessEnvironment
class (which you can patch.)gdb
will be suspended for a non-zero amount of time.ProcessBuilder
when spawning the process.Note that all methods above, except for the one involving ProcessBuilder
, are brittle, error prone, non-portable to various degrees, and prone to race conditions in multi-threaded environments.
You can get a handle on the underlying map that java.lang.ProcessEnvironment
is holding on to, and then put new stuff and remove stuff all you want.
This works on java 1.8.0_144. Can't guarantee it works on any other version of java, but it's probably similar if you really need to change the environment at run time.
private static Map<String,String> getModifiableEnvironment() throws Exception{ Class pe = Class.forName("java.lang.ProcessEnvironment"); Method getenv = pe.getDeclaredMethod("getenv"); getenv.setAccessible(true); Object unmodifiableEnvironment = getenv.invoke(null); Class map = Class.forName("java.util.Collections$UnmodifiableMap"); Field m = map.getDeclaredField("m"); m.setAccessible(true); return (Map) m.get(unmodifiableEnvironment); }
After you get the reference to the map, just add whatever you want and you can now retrieve it using the regular old System.getenv("")
call.
I tried this its working in MAC not working in Windows in both os java version 1.8_161
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