You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SBT中如何通过Shading实现AWS SDK用旧版Netty、项目用新版?

解决AWS SDK与项目Netty版本冲突的SBT Shading配置方案

问题背景

项目里的SBT配置如下:

val awssdk2 = "2.15.14"
val netty = "4.1.91.Final"

...
      "software.amazon.awssdk" % "kinesis"      % Versions.awssdk2,
      "io.netty"               % "netty-buffer" % Versions.netty

AWS SDK 2.15.14本身会依赖Netty 4.1.46.Final,但因为项目指定了更高的4.1.91.Final版本,依赖管理工具会自动用高版本覆盖低版本,结果导致AWS SDK与新Netty版本不兼容,抛出java.nio.channels.ClosedChannelException。

我们不想单独升级AWS SDK(项目构建文件规模庞大,需要通用的版本隔离机制),而是希望通过SBT的Shading功能实现版本隔离:让AWS SDK使用自身依赖的Netty 4.1.46.Final,项目其他代码(自研Netty逻辑、其他依赖Netty的库)则使用4.1.91.Final。

之前试过下面的Shading规则,但完全没用,仍出现相同错误:

assemblyShadeRules in assembly ++= Seq(
      ShadeRule.rename("io.netty.**" -> "aws2_version_of_netty.@1")
        .inLibrary("software.amazon.awssdk" % "kinesis" % Versions.awssdk2)
    ),

问题根源

之前的规则只针对kinesis这一个AWS SDK模块,但AWS SDK的Netty依赖分散在多个子模块中(比如netty-nio-client、http-client-spi等),仅给kinesis加规则覆盖不到所有用到Netty的AWS SDK代码;另外,也没处理项目全局Netty版本对AWS SDK依赖树的侵入。

正确配置方案

需要调整Shading规则,同时处理依赖排除和手动引入指定版本的Netty,具体配置如下:

// 第一步:给AWS SDK的kinesis排除所有Netty传递依赖,避免项目全局版本干扰
libraryDependencies ++= Seq(
  "software.amazon.awssdk" % "kinesis" % Versions.awssdk2 excludeAll(
    ExclusionRule(organization = "io.netty")
  ),
  // 手动引入AWS SDK原本依赖的Netty 4.1.46.Final全量模块
  "io.netty" % "netty-buffer" % "4.1.46.Final" % "compile",
  "io.netty" % "netty-codec" % "4.1.46.Final" % "compile",
  "io.netty" % "netty-codec-http" % "4.1.46.Final" % "compile",
  "io.netty" % "netty-codec-http2" % "4.1.46.Final" % "compile",
  "io.netty" % "netty-common" % "4.1.46.Final" % "compile",
  "io.netty" % "netty-handler" % "4.1.46.Final" % "compile",
  "io.netty" % "netty-resolver" % "4.1.46.Final" % "compile",
  "io.netty" % "netty-transport" % "4.1.46.Final" % "compile",
  "io.netty" % "netty-transport-native-epoll" % "4.1.46.Final" % "compile" classifier "linux-x86_64",
  "io.netty" % "netty-transport-native-kqueue" % "4.1.46.Final" % "compile" classifier "osx-x86_64"
)

// 第二步:配置Shading规则,把AWS SDK相关的Netty类全部重命名
assemblyShadeRules in assembly ++= Seq(
  ShadeRule.rename("io.netty.**" -> "aws2_version_of_netty.@1")
    // 覆盖所有AWS SDK中用到Netty的模块
    .inLibrary("software.amazon.awssdk" % "kinesis" % Versions.awssdk2)
    .inLibrary("software.amazon.awssdk" % "netty-nio-client" % Versions.awssdk2)
    .inLibrary("software.amazon.awssdk" % "http-client-spi" % Versions.awssdk2)
    // 把手动引入的Netty 4.1.46.Final模块也加入规则,确保类被重命名
    .inLibrary("io.netty" % "netty-buffer" % "4.1.46.Final")
    .inLibrary("io.netty" % "netty-codec" % "4.1.46.Final")
    .inLibrary("io.netty" % "netty-codec-http" % "4.1.46.Final")
    .inLibrary("io.netty" % "netty-codec-http2" % "4.1.46.Final")
    .inLibrary("io.netty" % "netty-common" % "4.1.46.Final")
    .inLibrary("io.netty" % "netty-handler" % "4.1.46.Final")
    .inLibrary("io.netty" % "netty-resolver" % "4.1.46.Final")
    .inLibrary("io.netty" % "netty-transport" % "4.1.46.Final")
    .inLibrary("io.netty" % "netty-transport-native-epoll" % "4.1.46.Final")
    .inLibrary("io.netty" % "netty-transport-native-kqueue" % "4.1.46.Final")
    // 确保项目中引用AWS SDK的代码能正确识别重命名后的类
    .inProject
)

配置说明

  1. 排除冲突传递依赖:给kinesis排除所有io.netty的依赖,防止项目全局的Netty版本替换AWS SDK原本的依赖。
  2. 手动引入指定版本Netty:根据AWS SDK 2.15.14的依赖树,把它原本依赖的所有Netty子模块都手动引入,这些模块会被Shading重命名,和项目全局的Netty完全隔离。
  3. 扩展Shading规则范围:不能只给kinesis加规则,必须覆盖所有AWS SDK中用到Netty的子模块,同时把手动引入的Netty模块也加入,确保所有相关的Netty类都被重命名。
  4. .inProject标记:添加这个标记是为了确保项目中调用AWS SDK的代码能正确访问重命名后的Netty类(核心是修正AWS SDK内部的类引用)。

内容的提问来源于stack exchange,提问作者samthebest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 15:53:15