Gradle构建找不到netty平台原生jar包的原因及解决方法
异常产生原因
该错误是依赖特性、Gradle Shadow插件解析逻辑、构建环境仓库配置三者共同导致的:
- Selenium 4.1.4会传递依赖Netty 4.1.76.Final版本,Netty的
netty-transport-native-epoll(Linux平台)、netty-transport-native-kqueue(macOS平台)属于带操作系统/架构分类器的平台原生依赖,默认不会被全量拉取,仅在匹配的运行环境下按需解析。 - 低版本Gradle Shadow插件在收集
runtimeClasspath时存在分类器依赖解析逻辑缺陷:不会仅匹配当前构建环境的原生包,而是会把所有平台对应的分类器变体都加入待解析列表,这也是报错中同时出现Linux x86_64、macOS x86_64两个平台jar包的核心原因。 - 云端环境构建失败的直接触发点:构建脚本仅配置了
mavenLocal()(本地Maven仓库)作为依赖源,从报错的搜索路径可以确认,云端本地Maven缓存里没有上述两个平台对应的Netty原生包,也没有配置远程仓库拉取缺失依赖,因此直接抛出解析失败错误。 - 本地编译正常、Maven Shade插件不报错的原因:本地环境的Gradle/Maven缓存中已经存在对应依赖,且Maven的依赖解析逻辑默认仅拉取当前构建环境匹配的原生包,不会跨平台扫描所有分类器变体,本地仓库缺失依赖时也会默认从中央仓库拉取,因此不会触发该错误。
修复方案
可根据实际构建场景选择以下方案,按落地成本从低到高排序:
- 方案1:给Gradle配置可用的远程Maven仓库,不要仅依赖本地Maven仓库。在
build.gradle.kts的repositories块中添加Maven中央仓库配置,缺失的依赖会自动从远程拉取:
repositories { mavenLocal() mavenCentral() // 新增该行,确保依赖可以从中央仓库拉取 }
- 方案2:升级Gradle Shadow插件到7.0及以上版本,新版本已经修复了跨平台分类器依赖被全量加入解析列表的问题,升级后仅会解析当前构建环境匹配的原生依赖,不会额外要求拉取其他平台的jar包。
- 方案3:如果构建环境不允许访问外部远程仓库,提前把对应系统架构的Netty native包上传到构建环境使用的私有Maven仓库/本地Maven缓存路径,需要的两个包坐标为:
io.netty:netty-transport-native-epoll:4.1.76.Final:linux-x86_64io.netty:netty-transport-native-kqueue:4.1.76.Final:osx-x86_64
- 方案4:如果不需要Netty的原生传输特性,可以在Selenium依赖声明中排除Netty原生传输相关的传递依赖,Shadow插件就不会再解析这部分依赖:
dependencies { val seleniumV = "4.1.4" api("org.seleniumhq.selenium:selenium-api:${seleniumV}") { exclude(group = "io.netty", module = "netty-transport-native-epoll") exclude(group = "io.netty", module = "netty-transport-native-kqueue") } api("org.seleniumhq.selenium:selenium-support:${seleniumV}") { exclude(group = "io.netty", module = "netty-transport-native-epoll") exclude(group = "io.netty", module = "netty-transport-native-kqueue") } }
注意:排除原生传输包后,Selenium会自动回退到NIO传输模式,绝大多数自动化场景下功能不受影响,仅高并发场景下的网络传输性能会比原生epoll/kqueue模式略低。
内容的提问来源于stack exchange,提问作者tribbloid
相关产品推荐
相关产品推荐

