如何在Java中设置环境变量而不出现“非法反射访问”?如何使用add-opens?

5
长话短说,我需要在运行时为特定的测试设置环境。
这里SO上的答案很好用,我正在使用this one。问题是我得到了这个警告:
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by **YOUR PACKAGE** (file: **YOUR FILE** ) to field java.util.Collections$UnmodifiableMap.m
WARNING: Please consider reporting this to the maintainers of **YOUR PACKAGE**
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

我已经开始寻找解决方案,这里的其他SO答案使用相同的方法来设置环境变量,以“解决”单元测试问题。
我在谈论他们的Github源代码中的这行代码,它会触发此错误。(field.setAccessible(true);
因此,看起来没有其他方法可以解决它,除了设置给定的标志,就像警告建议的那样。
然后我想知道这个警告是否严重,我的程序是否会在几个月内运行(我正在使用OpenJDK 11)。结果表明,这个非法访问设置将在未来版本中被删除。

来源:

如果您必须继续使用需要非法访问的组件,则可以使用一个或多个 --add-opens 选项来仅打开所需访问权限的内部包,以消除警告消息。

稍后:

为了验证您的应用程序已准备好迎接JDK的未来版本,请使用 --illegal-access=deny 以及任何必要的 --add-opens 选项运行它。

然后我开始寻找 --add-opens 需要的语法,但无法找到如何正确使用它。

我找到了这个,但我仍然不理解如何在 Kotlin 项目中使用它以及模块的名称是什么。

--add-opens module/package=target-module(,target-module)*/

将模块更新为打开 package 到 target-module,而不考虑模块声明。

如何使用--add-opens来启用对java.util.Collections$UnmodifiableMap.m的修改?我只需启用对此字段的add-opens,还是需要启用对整个java.util.Collection的add-opens?这样做合理吗?
实际上,我之所以要像这样完整地写出这个问题,是因为我在执行过程中可能存在某些不符合预期的操作。
感谢任何人的帮助。
2个回答

1
根据您已经引用的syntax,对于--add-opens,您只能在包级别上打开模块:
--add-opens module/package=target-module(,target-module)*

由于java.util.Collections属于java.base模块java.util包,因此您需要添加JVM参数。

--add-opens java.base/java.util=target-module(,target-module)*

你的目标模块必须是想要访问 java.util.Collections$UnmodifiableMap.mALL-UNNAMED 模块的模块。

--add-opens java.base/java.util=ALL-UNNAMED

0

现在,System Stubs v2.0.0使用Mockito提供了一个解决方案。

https://github.com/webcompere/system-stubs

它可以独立使用:

new EnvironmentVariables("SET_THIS_VAR", "toThis")
   .execute(() -> runThisCode());

或者有一个JUnit 5插件。

如果需要,其核心项目中的EnvironmentVariableMocker也可以单独使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接