JDK9以上的非法反射访问警告解决方法
1. 问题描述
JDK9
以上很多库都有这种非法反射访问的警告,比如protostuff
:
解决方法两个:
JDK
降级添加JVM
参数
2. 原因
降到JDK8
能解决以上问题。
但是这不是本文的重点。
先说一下出现该警告的原因,笔者使用的JDK为OpenJDK 11,JDK9以上模块不能使用反射去访问非公有的成员/成员方法以及构造方法,除非模块标识为opens去允许反射访问。旧JDK制作的库(JDK8及以下)运行在JDK9上会自动被标识为未命名模块
,为了处理该警告,JDK9以上提出了一个新的JVM参数:--illegal-access
。
3. –illegal-access
该参数有四个可选值:
permit
:默认值,允许通过反射访问,因此会提示像上面一样的警告,这个是首次非法访问警告,后续不警告;warn
:每次非法访问都会警告;debug
:在warn
的基础上加入了类似e.printStackTrace()
的功能;deny
:禁止所有的非法访问除了使用特别的命令行参数排除的模块,比如使用--add-opens
排除某些模块使其能够通过非法反射访问。
因此解决的办法很简单,将其设置为deny
,并添加--add-opens
开启对应的允许非法反射访问的模块即可。
可以通过先设置为debug
找到对应的非法访问的代码,比如protostuff
中的非法反射访问代码段如下:
这都是JDK
基本模块的代码,因此,添加--add-opens=java.base/java.lang.invoke=ALL-UNNAMED
即可。--add-opens
可以使模块中的包对其他模块开放,这样就可以在运行期使用深层反射访问该程序包中的所有成员类型。
4. 总结
因此解决的办法是添加如下两个JVM
参数:
--illegal-access=deny --add-opens java.base/java.lang=ALL-UNNAMED
IDEA
可以在运行配置中的VM options
中添加:
如果使用Maven
打包的时候还是会出现警告,可以在IDEA
中的Maven
配置中添加全局的Maven
参数:
另外,如果使用Gradle
而不是Maven
作为管理工具,Gradle
测试的时候还是会显示警告,尽管Gradle
运行配置里面有VM Options
选项:
但在这里添加是没用的,正确的做法是在build.gradle
中添加:
test { useJUnitPlatform() jvmArgs('--illegal-access=deny') jvmArgs('--add-opens', 'java.base/java.lang.invoke=ALL-UNNAMED') }
这样Gradle
测试也没有问题了。
1. 本站所有文章教程及资源素材均来源于网络与用户分享或为本站原创,仅限用于学习和研究。
2. 如果内容损害你的权益请联系客服QQ:1642748312给予处理。
码云笔记 » JDK9以上的非法反射访问警告解决方法