Environment variables truth source of the JVM (and how to mutate it)

Roger Riggs Roger.Riggs at Oracle.com
Wed May 10 13:47:58 UTC 2017


I'm not sure I have all the history.
The current implementation seems more complicated than necessary
by trying to avoid copying when not necessary and providing an unused
facility to provide access to binary values in the environment.

On 5/10/2017 9:30 AM, pierre at 2bst.fr wrote:
> Hi, I've been trying to understand how the JVM accesses environment
> variables and how they can be mutated.
> I sent an email about this list few hours ago on the general-purpose
> discuss mailing-list but it appears it would be better posted herein.
> For this I've made some assumptions and I would like to know if
> they'recorrect, could you help me on this?
> 1) It appears that the JVM gets a copy of its process environment
> variables and store them in static final fields
> theUnmodifiableEnvironment and theEnvironment of class
> java.lang.ProcessEnvironment.
> - My assumption is: these fields are the "truth source" about
>    environment variables inside the JVM and any attempt to access some of
>    them will end up in a lookup of this fields.
The supported access to the environment is System.getenv(String) and 
to get a Map of all of the values.
The environment is shared by all threads within a process and 
modification is not supported.
> - I have a question about this: why two final fields instead of only
>    one? Perhaps theUnmodifiableEnvironment stands for base JVM env whilst
>    theEnvironment is for env of current process (which could be changed
>    with Process.exec(String[] cmdarray, String[] envp, File dir))?
During construction of the environment a modifiable map is needed. When 
it is fully constructed
it is wrapped in an UnmodifiableMap so it cannot be modified when the 
map is returned from System.getenv().

Process.exec allows the environment to be supplied for *new* process, 
not to change
the environment for the current process.
> 2) There is a subtle way to mutate them in Sun JDK (see
> http://www.javaspecialists.eu/archive/Issue161.html).
> - My assumption is: These fields are passed to all new JVM threads, so
>    mutating them (as ugly as it can sound) will be JVM-wide and will
>    result in all thread getting mutated env as their environment
>    variables.
> - Sensitive question: is this enforced? System.getenv() appears to
>    correctly returns mutated env, can I deduce all new threads in the JVM
>    will get mutated values?
> - Another sensitive question: as these fields are static final, can I
>    deduce all threads in the JVM will get mutated values, not only new
>    ones?
Don't do it.
It breaks the encapsulation and can cause unexpected behavior in code 
that uses
environment variables.

Can you share your use case and rationale for breaking into the API?


> It would be my pleasure to provide further details ifneedsbe. Just let
> me know if some of the above assumptions are incorrect!
> Yours faithfully,
> p2b

More information about the core-libs-dev mailing list