同一Gatling依赖引入不同Netty版本?报错原因与解决问询
Gatling性能测试Netty版本冲突问题排查与解决
问题背景
运行Gatling性能测试时,某API在HttpProtocolBuilder阶段抛出以下错误:
Exception in thread "main" java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.CommandLineWrapper.main(CommandLineWrapper.java:64) Caused by: java.lang.NoSuchFieldError: DNT at io.gatling.http.HeaderNames$.<clinit>(Headers.scala:44) at io.gatling.http.HttpDsl.$init$(HttpDsl.scala:52) at io.gatling.http.Predef$.<clinit>(Predef.scala:19)
经排查,正常运行的API依赖的Netty版本为:
[INFO] | | +- io.gatling:gatling-http:jar:3.7.6:test [INFO] | | | \- io.gatling:gatling-http-client:jar:3.7.6:test [INFO] | | | +- io.netty:netty-handler-proxy:jar:4.1.65.Final:test [INFO] | | | | \- io.netty:netty-codec-socks:jar:4.1.65.Final:test [INFO] | | | +- io.netty:netty-resolver-dns:jar:4.1.65.Final:test [INFO] | | | | \- io.netty:netty-codec-dns:jar:4.1.65.Final:test [INFO] | | | +- io.netty:netty-codec-http2:jar:4.1.65.Final:test [INFO] | | | +- io.netty:netty-tcnative-boringssl-static:jar:2.0.39.Final:test
报错的API依赖的Netty版本为:
[INFO] | | +- io.gatling:gatling-http:jar:3.7.6:test [INFO] | | | \- io.gatling:gatling-http-client:jar:3.7.6:test [INFO] | | | +- io.netty:netty-handler-proxy:jar:4.1.31.Final:test [INFO] | | | | \- io.netty:netty-codec-socks:jar:4.1.31.Final:test [INFO] | | | +- io.netty:netty-resolver-dns:jar:4.1.31.Final:test [INFO] | | | | \- io.netty:netty-codec-dns:jar:4.1.31.Final:test [INFO] | | | +- io.netty:netty-codec-http2:jar:4.1.31.Final:test [INFO] | | | +- io.netty:netty-tcnative-boringssl-static:jar:2.0.20.Final:test
疑问
为何同一Gatling库依赖下,不同API会引入不同版本的Netty?该如何解决此问题?
问题原因
- 依赖传递优先级冲突:报错的API项目中存在其他直接/间接依赖,引入了更低版本的Netty,且该版本在依赖管理工具(如Maven/Gradle)的解析规则中优先级更高,覆盖了Gatling自带的Netty版本。
- API兼容性问题:
DNT请求头字段是Netty 4.1.48+版本新增的,而报错场景使用的4.1.31.Final版本无此字段,Gatling 3.7.6的代码会调用该字段,因此抛出NoSuchFieldError。
解决方法
1. 强制统一Netty版本(Maven示例)
在项目pom.xml的dependencyManagement节点中,强制指定所有Netty组件版本为Gatling兼容的4.1.65.Final:
<dependencyManagement> <dependencies> <!-- 统一所有Netty模块版本 --> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.65.Final</version> </dependency> <!-- 或逐个指定冲突模块(可选) --> <dependency> <groupId>io.netty</groupId> <artifactId>netty-handler-proxy</artifactId> <version>4.1.65.Final</version> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-resolver-dns</artifactId> <version>4.1.65.Final</version> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-codec-http2</artifactId> <version>4.1.65.Final</version> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-tcnative-boringssl-static</artifactId> <version>2.0.39.Final</version> </dependency> </dependencies> </dependencyManagement>
2. 排查并排除冲突依赖
用mvn dependency:tree命令找出引入低版本Netty的根源依赖,然后在该依赖声明中排除Netty组件:
<dependency> <groupId>com.example</groupId> <artifactId>xxx-api-client</artifactId> <version>1.0.0</version> <exclusions> <exclusion> <groupId>io.netty</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency>
3. 验证依赖一致性
修改后执行mvn dependency:tree确认所有Netty相关依赖版本统一为4.1.65.Final,再重新运行Gatling测试。
内容的提问来源于stack exchange,提问作者Kris
相关产品推荐
相关产品推荐

