Netty 4.1.5.Final出现IllegalAccessError问题求助
这问题我之前在生产环境碰过类似的,核心原因基本逃不开Netty版本冲突或者类加载器隔离异常,咱们一步步来解决:
一、先定位核心原因
你遇到的java.lang.IllegalAccessError是因为当前代码试图访问io.netty.channel.AdaptiveRecvByteBufAllocator$HandleImpl这个内部类,但权限不允许——大概率是不同版本的Netty中,这个类的访问修饰符发生了变化(比如从包私有改成私有,或者反过来),而你的项目里同时存在多个版本的Netty依赖,导致类加载混乱。
另外Netty持续抛数千条错误,是因为它的事件循环线程在报错后会不断重试连接/处理逻辑,所以先解决根因才能终止这些错误。
二、具体解决步骤
1. 排查并统一Netty版本
首先用依赖分析工具找出项目中所有Netty的版本:
- Maven项目执行:
mvn dependency:tree | grep netty - Gradle项目执行:
./gradlew dependencies | grep netty
你会发现Riak客户端依赖的Netty版本,和你项目中其他依赖(比如Spring Web、其他RPC框架)带的Netty版本不一致。接下来需要统一版本:
- 如果用Maven,在
dependencyManagement中指定统一的Netty版本:
<dependencyManagement> <dependencies> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.94.Final</version> <!-- 选择和你Riak客户端兼容的版本,比如查看Riak客户端pom.xml里的依赖版本 --> </dependency> </dependencies> </dependencyManagement>
- 同时排除Riak客户端中自带的Netty依赖,避免冲突:
<dependency> <groupId>com.basho.riak</groupId> <artifactId>riak-client</artifactId> <version>你的Riak客户端版本</version> <exclusions> <exclusion> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> </exclusion> </exclusions> </dependency>
2. 检查类加载器隔离问题(如果是容器/微服务环境)
如果是在Tomcat、Spring Boot Fat Jar或者其他容器中运行,可能存在类加载器隔离导致的问题:
- Spring Boot项目:检查是否有自定义的类加载器配置,或者某些依赖被标记为
provided但实际需要被统一加载 - Tomcat容器:确保Netty的jar包只放在
WEB-INF/lib下,不要同时在Tomcat的lib目录中存在其他版本的Netty - 微服务框架(比如Dubbo):检查是否有框架层面的类加载器配置,导致Netty类被不同加载器加载
3. 排查Shadow Jar打包问题
如果你的项目用了Shadow Jar(比如Gradle Shadow Plugin、Maven Shade Plugin)打包,可能出现不同版本的Netty类被合并到同一个jar中,导致类冲突:
- 在打包插件配置中,添加Netty类的统一规则,比如优先保留指定版本的类,排除其他版本的重复类
- 或者在打包前先完成依赖版本统一,再执行打包操作
三、验证解决效果
修改依赖后,重新打包部署,观察是否还会出现IllegalAccessError,以及Netty的错误日志是否停止。如果还有问题,可以添加JVM参数-verbose:class来打印类加载日志,定位到底是哪个类加载器加载了哪个版本的Netty类,进一步排查。
内容的提问来源于stack exchange,提问作者Dio

