-
Type:
Bug
-
Status: Resolved
-
Priority:
P4
-
Resolution: Incomplete
-
Affects Version/s: 12.0.1
-
Fix Version/s: None
-
Component/s: core-libs
-
Subcomponent:
-
CPU:x86_64
-
OS:windows_10
ADDITIONAL SYSTEM INFORMATION :
Windows 10 / Java 12
A DESCRIPTION OF THE PROBLEM :
After migrating from Java 10 to Java 12 the implementation of java.lang.ProcessEnvironment String getenv(String name) was modified and it's not using the same map as the Map<String,String> getenv() to look for the variables.
In Java 10 both methods were using the "theUnmodifiableEnvironment" map. In Java 12 the getenv() continues to use the "theUnmodifiableEnvironment" and the getenv(String name) is using the "theCaseInsensitiveEnvironment" map.
During my develpment I put some variables in the "theUnmodifiableEnvironment" via java.lang.System:
Map<String, String> envMap = System.getenv();
Class<?> cl = envMap.getClass();
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
Map<String, String> writableEnv = (Map<String, String>) field.get(envMap);
writableEnv.put("DB_URL", env.getRequiredProperty("DB_URL"));
writableEnv.put("DB_USER", env.getRequiredProperty("DB_USER"));
writableEnv.put("DB_PASSWORD", env.getRequiredProperty("DB_PASSWORD"));
writableEnv.put("DB_AMBIENTE", env.getRequiredProperty("DB_AMBIENTE"));
But later when I try to get those properties back, I get a null value:
TenantInfo tenantInfo = new TenantInfo();
tenantInfo.setTenantId(SINGLE_TENANT_KEY);
tenantInfo.setUrl(System.getenv("DB_URL"));
tenantInfo.setUserName(System.getenv("DB_USER"));
tenantInfo.setPassword(System.getenv("DB_PASSWORD"));
tenantInfo.setDriverClassName("oracle.jdbc.OracleDriver");
The problem is not in the System class. The problemis in the ProcessEnvironment class
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Get the environment variables via reflection from the System:
Map<String, String> envMap = System.getenv();
Class<?> cl = envMap.getClass();
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
Map<String, String> writableEnv = (Map<String, String>) field.get(envMap);
writableEnv.put("MY_VARIABLE", "ANY_VALUE");
Later try to acces the same variable:
System.getenv("MY_VARIABLE")
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Expected to get "ANY_VALUE"
---------- BEGIN SOURCE ----------
public class Teste {
public static void main(String[] args) {
try {
Map<String, String> envMap = System.getenv();
Class<?> cl = envMap.getClass();
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
Map<String, String> writableEnv = (Map<String, String>) field.get(envMap);
writableEnv.put("MY_VARIABLE", "ANY_VALUE");
if(System.getenv("MY_VARIABLE") == null) {
throw new Exception("COULDN'T FIND THE VARIABLE VALUE");
}
} catch (Exception e) {
System.out.println(e);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Instead of using
System.getenv("MY_VARIABLE")
use
System.getenv().get("MY_VARIABLE")
FREQUENCY : always
Windows 10 / Java 12
A DESCRIPTION OF THE PROBLEM :
After migrating from Java 10 to Java 12 the implementation of java.lang.ProcessEnvironment String getenv(String name) was modified and it's not using the same map as the Map<String,String> getenv() to look for the variables.
In Java 10 both methods were using the "theUnmodifiableEnvironment" map. In Java 12 the getenv() continues to use the "theUnmodifiableEnvironment" and the getenv(String name) is using the "theCaseInsensitiveEnvironment" map.
During my develpment I put some variables in the "theUnmodifiableEnvironment" via java.lang.System:
Map<String, String> envMap = System.getenv();
Class<?> cl = envMap.getClass();
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
Map<String, String> writableEnv = (Map<String, String>) field.get(envMap);
writableEnv.put("DB_URL", env.getRequiredProperty("DB_URL"));
writableEnv.put("DB_USER", env.getRequiredProperty("DB_USER"));
writableEnv.put("DB_PASSWORD", env.getRequiredProperty("DB_PASSWORD"));
writableEnv.put("DB_AMBIENTE", env.getRequiredProperty("DB_AMBIENTE"));
But later when I try to get those properties back, I get a null value:
TenantInfo tenantInfo = new TenantInfo();
tenantInfo.setTenantId(SINGLE_TENANT_KEY);
tenantInfo.setUrl(System.getenv("DB_URL"));
tenantInfo.setUserName(System.getenv("DB_USER"));
tenantInfo.setPassword(System.getenv("DB_PASSWORD"));
tenantInfo.setDriverClassName("oracle.jdbc.OracleDriver");
The problem is not in the System class. The problemis in the ProcessEnvironment class
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Get the environment variables via reflection from the System:
Map<String, String> envMap = System.getenv();
Class<?> cl = envMap.getClass();
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
Map<String, String> writableEnv = (Map<String, String>) field.get(envMap);
writableEnv.put("MY_VARIABLE", "ANY_VALUE");
Later try to acces the same variable:
System.getenv("MY_VARIABLE")
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Expected to get "ANY_VALUE"
---------- BEGIN SOURCE ----------
public class Teste {
public static void main(String[] args) {
try {
Map<String, String> envMap = System.getenv();
Class<?> cl = envMap.getClass();
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
Map<String, String> writableEnv = (Map<String, String>) field.get(envMap);
writableEnv.put("MY_VARIABLE", "ANY_VALUE");
if(System.getenv("MY_VARIABLE") == null) {
throw new Exception("COULDN'T FIND THE VARIABLE VALUE");
}
} catch (Exception e) {
System.out.println(e);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Instead of using
System.getenv("MY_VARIABLE")
use
System.getenv().get("MY_VARIABLE")
FREQUENCY : always