Reputation: 1263
I am trying to set environment variable through a unit test, when I am running my code on the local machine it is working fine.
But when I deploying it on Jenkins pipeline it starts throwing an exception.
Exception :-
java.lang.NoSuchFieldException: theCaseInsensitiveEnvironment
Code snippet :-
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.clear();
env.putAll(newenv);
Field theCaseInsensitiveEnvironmentField = processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment");
theCaseInsensitiveEnvironmentField.setAccessible(true);
Map<String, String> cienv = (Map<String, String>) theCaseInsensitiveEnvironmentField.get(null);
cienv.clear();
cienv.putAll(newenv);
Upvotes: 0
Views: 1744
Reputation: 1947
That field probably doesn't exist on your java.lang.ProcessEnvironment
class.
A quick check should show you all the actual fields you have access to:
Class<?> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
for (Field field : processEnvironmentClass.getDeclaredFields()) {
System.out.print(field.getName() + "\n");
}
In my case, I ran into the same error, and quickly discovered the only fields my ProcessEnvironment
has are the following:
theEnvironment
theUnmodifiableEnvironment
MIN_NAME_LENGTH
My best understanding is that theEnvironment
has replaced theCaseInsensitiveEnvironment
, and what you actually want to also replace is theUnmodifiableEnvironment
, so that your code reads like so:
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.clear();
env.putAll(newenv);
Field theUnmodifiableEnvironmentField = processEnvironmentClass.getDeclaredField("theUnmodifiableEnvironment");
theUnmodifiableEnvironmentField.setAccessible(true);
Map<String, String> umenv = (Map<String, String>) theCaseInsensitiveEnvironmentField.get(null);
umenv.clear();
umenv.putAll(newenv);
I'm assuming you're following something like https://sites.google.com/site/androcoding/classroom-news/howtosetenvironmentparametersusingjava from 2012, and our ProcessEnvironment
class is just different in the version of Java we're using now in what fields it has.
Upvotes: -1
Reputation: 299148
You're fixing the wrong problem. Your business code should never directly depend on environment variable, there should be an isolation layer in between. Decouple your input from your service code, and you will no longer need to mock environment variables.
Upvotes: 2