1 问题描述

JDK9以上很多库都有这种非法反射访问的警告,比如protostuff

解决方法两个:

  • JDK降级
  • 添加JVM参数

2 原因

降到JDK8能解决以上问题。

但是这不是本文的重点。

先说一下出现该警告的原因,笔者使用的JDKOpenJDK 11JDK9以上模块不能使用反射去访问非公有的成员/成员方法以及构造方法,除非模块标识为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测试也没有问题了。

5 参考

解决JDK9以上的非法反射访问警告的更多相关文章

  1. [C#] 解决Silverlight反射安全关键(SecuritySafeCritical)时报“System.MethodAccessException: 安全透明方法 XXX 无法使用反射访问”的问题

    作者: zyl910 一.缘由 在Silverlight中使用反射动态访问时,经常遇到"System.MethodAccessException: 安全透明方法 XXX 无法使用反射访问-- ...

  2. java中用反射访问私有方法和私有成员[转]

    转自: http://zhouyangchenrui.iteye.com/blog/470521 java的反射可以绕过访问权限,访问到类的私有方法和成员.可能这点会引起安全性的讨论.反射的使用帮助解 ...

  3. 解决mysql中只能通过localhost访问不能通过ip访问的问题

    解决mysql中只能通过localhost访问不能通过ip访问的问题 原因是没开权限 SELECT * FROM USER WHERE USER='root'; grant all privilege ...

  4. 解决nginx发布网站跨目录访问

    解决nginx发布网站跨目录访问(thinkphp5+lnmp) 到:usr/local/nginx/conf/vim fastcgi.cof 把最后一行加上井号#注释掉保存重启 restart 参考 ...

  5. 我的Android进阶之旅------>如何解决Android 5.0中出现的警告: Service Intent must be explicit:

    我的Android进阶之旅-->如何解决Android 5.0中出现的警告: java.lang.IllegalArgumentException: Service Intent must be ...

  6. java利用反射访问类的私有(private)属性及方法

    Java语言中,在一个类中,为了不让外界访问到有的属性和方法,通常将其设置为private,用正常的方式(对象名.属性名,对象名.方法名)将无法访问此属性与方法,但有没有其他方法可以访问呢?答案是有的 ...

  7. 我的Android进阶之旅------>怎样解决Android 5.0中出现的警告: Service Intent must be explicit:

    我的Android进阶之旅-->怎样解决Android 5.0中出现的警告: java.lang.IllegalArgumentException: Service Intent must be ...

  8. 解决IntelliJ IDEA的Plugins无法访问Marketplace去下载插件

    本文图文讲解如何解决IntelliJ IDEA的Plugins无法访问Marketplace去下载插件. 默认打开IDEA的Plugins会加载很久,最后什么也没加载出来. 这时我们可以给插件市场设置 ...

  9. .net 反射访问私有变量和私有方法 如何创建C# Closure ? C# 批量生成随机密码,必须包含数字和字母,并用加密算法加密 C#中的foreach和yield 数组为什么可以使用linq查询 C#中的 具名参数 和 可选参数 显示实现接口 异步CTP(Async CTP)为什么那样工作? C#多线程基础,适合新手了解 C#加快Bitmap的访问速度 C#实现对图片文件的压

    以下为本次实践代码: using System; using System.Collections.Generic; using System.ComponentModel; using System ...

随机推荐

  1. Java volatile 关键字底层实现原理解析

    本文转载自Java volatile 关键字底层实现原理解析 导语 在Java多线程并发编程中,volatile关键词扮演着重要角色,它是轻量级的synchronized,在多处理器开发中保证了共享变 ...

  2. Java自学第2期——注释、数据类型、运算符、方法

    2.1.注释 注释用于说明某段代码的作用,某个类的用途,某个方法的功能,参数和返回值数据类型的意义等等: 注释非常非常非常重要,回顾代码时通过注释找回思路:团队沟通需要,让别人读懂你的代码,增加效率: ...

  3. 基于股票大数据分析的Python入门实战(视频教学版)的精彩插图汇总

    在我写的这本书,<基于股票大数据分析的Python入门实战(视频教学版)>里,用能吸引人的股票案例,带领大家入门Python的语法,数据分析和机器学习. 京东链接是这个:https://i ...

  4. Python序列之列表(一)

    在Python中,列表是一种常用的序列,接下来我来讲一下关于Python中列表的知识. 列表的创建 Python中有多种创建列表的方式 1.使用赋值运算符直接赋值创建列表 在创建列表时,我们直接使用赋 ...

  5. iframe 调用父页面元素

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="IFrame.aspx.cs ...

  6. eclipse快速定位当前类所在位置

    如何快速的找到一个类并且定位它所在的位置呢?这里以搜索Menu类为例说明. 可以通过CTRL + SHIFT +R的组合键,输入Menu 双击Menu.java即可跳转到对应的类上,但此时还不知道此类 ...

  7. Linux解压缩相关命令

    Linux解压缩相关命令 运行级别: 0:关机 1:单用户 2:多用户无网络连接 3:多用户有网络连接 4:系统保留 5:图形界面 6:系统重启 通过init[0123456]来切换不同的运行级别 g ...

  8. 后端程序员之路 8、一种内存kv数据库的实现

    键值(Key-Value)存储数据库,这是一种NoSQL(非关系型数据库)模型,其数据按照键值对的形式进行组织.索引和存储.KV存储非常适合不涉及过多数据关系业务关系的业务数据,同时能有效减少读写磁盘 ...

  9. Mybatis检查SQL注入

    Mybatis 的 Mapper.xml 语句中 parameterType 向SQL语句传参有两种方式:#{ } 和 ${ }. 使用#{ }是来防止SQL注入,使用${ }是用来动态拼接参数. 如 ...

  10. 180. 连续出现的数字 + MySql + 连续出现数字 + 多表联合查询

    180. 连续出现的数字 LeetCode_MySql_180 题目描述 代码实现 # Write your MySQL query statement below select distinct t ...