【问题标题】:Jenkins throw java.lang.NoSuchFieldException: theCaseInsensitiveEnvironment詹金斯抛出 java.lang.NoSuchFieldException: theCaseInsensitiveEnvironment
【发布时间】:2020-07-14 14:46:15
【问题描述】:

我正在尝试通过单元测试设置环境变量,当我在本地机器上运行我的代码时它工作正常。

但是当我在 Jenkins 管道上部署它时,它开始抛出异常。

例外:-

java.lang.NoSuchFieldException: theCaseInsensitiveEnvironment

代码 sn-p :-

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);

【问题讨论】:

标签: java unit-testing jenkins reflection environment-variables


【解决方案1】:

您正在解决错误的问题。你的业务代码不应该直接依赖于环境变量,两者之间应该有一个隔离层。将您的输入与您的服务代码分离,您将不再需要模拟环境变量。

【讨论】:

    【解决方案2】:

    java.lang.ProcessEnvironment 类中可能不存在该字段。

    快速检查应该会显示您可以访问的所有实际字段:

    Class<?> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
    for (Field field : processEnvironmentClass.getDeclaredFields()) {
        System.out.print(field.getName() + "\n");
    }
    

    在我的例子中,我遇到了同样的错误,并很快发现我的ProcessEnvironment 的唯一字段如下:

    theEnvironment
    theUnmodifiableEnvironment
    MIN_NAME_LENGTH
    

    我最好的理解是theEnvironment已经替换了theCaseInsensitiveEnvironment,而你真正想要替换的是theUnmodifiableEnvironment,所以你的代码是这样的:

    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);
    

    我假设您从 2012 年开始关注 https://sites.google.com/site/androcoding/classroom-news/howtosetenvironmentparametersusingjava 之类的内容,而我们的 ProcessEnvironment 类在我们现在使用的 Java 版本中的不同字段中有所不同。

    【讨论】:

    • umenv putAll 将抛出 java.lang.UnsupportedOperationException 这是一个 UnmodifiableMap 不支持更新 public void putAll(Map extends K, ? extends V> m) { throw new UnsupportedOperationException(); }
    猜你喜欢
    • 1970-01-01
    • 2019-09-02
    • 1970-01-01
    • 2020-07-04
    • 1970-01-01
    • 2018-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多