升级jdk11后出现告警信息解决方案,An illegal reflective access operation has occurred

本文介绍了解决Java应用程序中出现的非法反射警告的方法。通过在启动类中加入特定代码,可以禁用这些警告,确保使用Java 11及更高版本运行程序时不会受到非法反射操作的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

告警信息:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils (file:/D:/dev/m2/org/springframework/spring-core/5.1.9.RELEASE/spring-core-5.1.9.RELEASE.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils
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

解决方案:

启动类增加忽略非法反射告警:

package com.xxx.xxxx;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@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) {
        }
    }
}

 

参考:忽略非法反射警告 An illegal reflective access operation has occurred_彦楠的博客-优快云博客

### 解决 Java 中 'illegal reflective access operation' 错误的方法 #### 1. **理解错误原因** 非法反射访问操作通常发生在尝试通过反射机制访问 JDK 的内部类或方法时。自 Java 9 起,模块化系统(Project Jigsaw)引入了更严格的封装规则,限制了对某些包的直接访问[^1]。 --- #### 2. **解决方案** ##### 方法一:调整 JVM 参数 可以通过设置 JVM 启动参数来允许非法反射访问操作。具体参数如下: - `--add-exports`:用于导出指定模块中的包到其他模块。 - `--add-opens`:用于打开指定模块中的包以便对其进行深度反射操作(如调用 `setAccessible(true)`)。 对于深层次的反射需求,推荐使用 `--add-opens`[^4]。 示例配置: ```bash --add-opens java.base/java.lang=ALL-UNNAMED ``` 此命令表示将 `java.base` 模块下的 `java.lang` 包开放给未命名模块(即默认的应用程序上下文),从而避免非法反射访问警告[^5]。 --- ##### 方法二:禁用非法访问行为 如果希望完全阻止非法反射访问操作并强制修复代码,则可以在 JVM 参数中添加以下选项: ```bash --illegal-access=deny ``` 这会立即抛出异常而不是仅发出警告,适用于严格模式开发环境[^5]。 --- ##### 方法三:升级依赖库 部分非法反射访问可能来源于第三方库(例如 Gradle 或 Android Studio 插件)。更新这些工具至最新版本可能会解决问题,因为新版本往往已经适配了最新的 JDK 版本及其安全策略[^3]。 --- ##### 方法四:重构代码逻辑 尽量减少对私有字段或方法的直接访问。如果确实需要访问某个类的功能,建议联系该类的设计者提供合法接口而非绕过其保护机制。例如,在上述案例中,不应直接获取 `sun.misc.Unsafe` 实例,而应寻找替代实现方式[^1]。 --- #### 示例修正后的代码 以下是经过修改以兼容现代 JDK 的代码片段: ```java import java.lang.reflect.Field; public class ReflectionExample { public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("sun.misc.Unsafe"); // 如果必须使用反射,请确保 JVM 配置支持 --add-opens Field field = clazz.getDeclaredField("theUnsafe"); field.setAccessible(true); Object unsafeInstance = field.get(null); System.out.println("Unsafe instance obtained: " + unsafeInstance); } } ``` 注意:运行前需确认已添加适当 JVM 参数,如 `--add-opens java.base/sun.misc=ALL-UNNAMED`[^4]。 --- ### 总结 解决 `'illegal reflective access operation'` 错误会因场景不同有所差异。一般优先考虑调整 JVM 参数作为临时措施;长期来看,优化代码设计、迁移到官方 API 并保持软件栈最新状态才是根本之道。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值