问题产生:
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
解决办法:
1.降级到jdk8
2.启动类,增加忽略非法反射警告的办法
@SpringBootApplication
public class XxxxApplication {
public static void main(String[] args) {
// 调用方法
disableAccessWarnings(); // 忽略非法反射警告
SpringApplication.run(XxxxApplication .class, args);
}
/**
* 忽略非法反射警告 适用于jdk11
*/
@SuppressWarnings("unchecked")
public static void disableAccessWarnings() {
try {
Class unsafeClass = Class.forName("sun.misc.Unsafe");
Field field = unsafeClass.getDeclaredField("theUnsafe");
field.setAccessible(true);
Object unsafe = field.get(null);
Method putObjectVolatile =
unsafeClass.getDeclaredMethod("putObjectVolatile", Object.class, long.class, Object.class);
Method staticFieldOffset = unsafeClass.getDeclaredMethod("staticFieldOffset", Field.class);
Class loggerClass = Class.forName("jdk.internal.module.IllegalAccessLogger");
Field loggerField = loggerClass.getDeclaredField("logger");
Long offset = (Long)staticFieldOffset.invoke(unsafe, loggerField);
putObjectVolatile.invoke(unsafe, loggerClass, offset, null);
} catch (Exception ignored) {
}
}
}
3.配置JVM 的参数
--illegal-access
该参数有四个可选值:
permit:默认值,允许通过反射访问,因此会提示像上面一样的警告,这个是首次非法访问警告,后续不警告
warn:每次非法访问都会警告
debug:在warn的基础上加入了类似e.printStackTrace()的功能
deny:禁止所有的非法访问除了使用特别的命令行参数排除的模块,比如使用--add-opens排除某些模块使其能够通过非法反射访问
要验证您的应用程序是否已为 JDK 的未来版本做好准备,请将它--illegal-access=deny
与任何必要的--add-opens
选项一起运行。任何剩余的非法访问错误很可能是由于从编译代码到 JDK 内部 API 的静态引用。您可以通过运行带有该选项的jdeps工具来识别这些--jdk-internals
。出于性能原因,当前的 JDK 不会对非法静态访问操作发出警告。
--add-opens
只能在包级别打开模块:
--add-opens module/package=target-module(,target-module)*
范例:(1) 由于java.util.Collections
属于模块中的中的java.util
包,因此必须添加JVM参数
--add-opens java.base/java.util=target-module(,target-module)*
(2)目标模块必须是要访问java.util.Collections$UnmodifiableMap.m
或ALL-UNNAMED
模块的模块
--add-opens java.base/java.util=ALL-UNNAMED