How to change environment variables in Java

And the second dirty hack for the day: how to change system environment variables in Java — at least during the lifetime of a JVM.

This can be useful when testing functionality that accesses environment variables set by container runtime like Docker.

public class EnvironmentsTest { @Test public void testGetFoobar() throws Exception { assertNull( System .getenv( " FOOBAR_ENV " )); injectEnvironmentVariable( " FOOBAR_ENV " , " Foo " ); assertThat( System .getenv( " FOOBAR_ENV " ), is( " Foo " )); } private static void injectEnvironmentVariable( String key, String value) throws Exception { Class <?> processEnvironment = Class .forName( " java.lang.ProcessEnvironment " ); Field unmodifiableMapField = getAccessibleField(processEnvironment, " theUnmodifiableEnvironment " ); Object unmodifiableMap = unmodifiableMapField.get( null ); injectIntoUnmodifiableMap(key, value, unmodifiableMap); Field mapField = getAccessibleField(processEnvironment, " theEnvironment " ); Map < String , String > map = ( Map < String , String >) mapField.get( null ); map.put(key, value); } private static Field getAccessibleField( Class <?> clazz, String fieldName) throws NoSuchFieldException { Field field = clazz.getDeclaredField(fieldName); field.setAccessible( true ); return field; } private static void injectIntoUnmodifiableMap( String key, String value, Object map) throws ReflectiveOperationException { Class unmodifiableMap = Class .forName( " java.util.Collections$UnmodifiableMap " ); Field field = getAccessibleField(unmodifiableMap, " m " ); Object obj = field.get(map); (( Map < String , String >) obj).put(key, value); } }

This is a very dirty hack, that relies on internals of the JDK, so please do use with care and of course only in testing scenarios. Also, this solution only works in more recent versions of JDK 1.8 — before that the internal maps were split up and named differently :-)

You may want to consider changing you code to insert another abstraction for the environment setting — to make the configuration changeable.

Found the post useful? Subscribe to my newsletter for more free content, tips and tricks on IT & Java:

Success! Now check your email to confirm your subscription.

All opinions are my own and do not reflect those of my employer or colleagues.