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

Scala项目导入不同版本Elasticsearch库失败及Shading方案异常

解决Scala中同时依赖Elasticsearch 6.x(Elastic4s)和7.x客户端的依赖冲突问题

我帮你梳理下这个问题:你要连接两个不同版本的ES集群,同时引入了Elastic4s 6.2.8(依赖ES 6.x客户端)和ES官方7.2.0的客户端,结果因为两者共用相同的包名导致依赖冲突。你尝试用sbt-assembly的shading来隔离,但配置有几个关键错误,导致shading没生效,导入类时报错。

问题根源

你的shading配置犯了两个核心错误:

  1. 规则被覆盖:每次使用assemblyShadeRules in assembly := Seq(...)都是重新赋值,会覆盖之前的所有规则,最后只有最后一条规则生效,前面的7.x和6.x客户端的shading完全没被应用。
  2. 包匹配错误&遗漏依赖:你写的org.elasticsearch.elasticsearch.**是错误的ES核心包路径,正确的根路径是org.elasticsearch.**;另外你只单独shaded了6.x的客户端,没处理Elastic4s本身依赖的ES 6.x相关包。

正确的解决方案

下面是修正后的build.sbt配置,以及代码中如何使用shaded后的客户端:

1. 完整的build.sbt配置

val elastic4sVersion = "6.2.8"
val es7Version = "7.2.0"

// 声明所有依赖
libraryDependencies ++= Seq(
  // Elasticsearch 7.x 官方核心库与高级客户端
  "org.elasticsearch" % "elasticsearch" % es7Version,
  "org.elasticsearch.client" % "elasticsearch-rest-high-level-client" % es7Version,
  // Elastic4s 6.x 客户端库
  "com.sksamuel.elastic4s" %% "elastic4s-core" % elastic4sVersion,
  "com.sksamuel.elastic4s" %% "elastic4s-http" % elastic4sVersion
)

// 配置Shading规则:用++=追加规则,避免覆盖
assemblyShadeRules in assembly ++= Seq(
  // 将ES 7.x的所有相关包重命名到shaded.es7路径下
  ShadeRule.rename("org.elasticsearch.**" -> "shaded.es7.@1")
    .inLibrary("org.elasticsearch" % "elasticsearch" % es7Version)
    .inLibrary("org.elasticsearch.client" % "elasticsearch-rest-high-level-client" % es7Version)
    .inAll, // 应用到所有依赖和项目代码中
  
  // 将Elastic4s依赖的ES 6.x相关包重命名到shaded.es6路径下
  // 先通过`sbt dependencyTree`确认Elastic4s依赖的ES版本,这里是6.2.2
  ShadeRule.rename("org.elasticsearch.**" -> "shaded.es6.@1")
    .inLibrary("org.elasticsearch" % "elasticsearch" % "6.2.2")
    .inLibrary("org.elasticsearch.client" % "elasticsearch-rest-client" % "6.2.2")
    .inLibrary("com.sksamuel.elastic4s" %% "elastic4s-core" % elastic4sVersion)
    .inLibrary("com.sksamuel.elastic4s" %% "elastic4s-http" % elastic4sVersion)
    .inAll
)

2. 代码中使用Shaded后的客户端

  • 连接ES 7.x集群:导入shaded后的7.x客户端类
import shaded.es7.org.elasticsearch.client.RestHighLevelClient
import shaded.es7.org.elasticsearch.client.RestClient

// 构建ES 7.x客户端
val es7Client = new RestHighLevelClient(
  RestClient.builder(new HttpHost("es7-host", 9200, "http"))
)

// 执行查询
val searchResponse = es7Client.search(...)
  • 连接ES 6.x集群(使用Elastic4s):导入shaded后的Elastic4s类
import shaded.es6.com.sksamuel.elastic4s.http.HttpClient
import shaded.es6.com.sksamuel.elastic4s.ElasticDsl._

// 构建Elastic4s客户端
val es6Client = HttpClient("http://es6-host:9200")

// 执行Elastic4s查询
val result = es6Client.execute {
  search("my-index-6").query(matchAllQuery)
}.await

println(result.hits.hits.map(_.source))

3. 注意事项

  • 必须使用sbt assembly打包后运行,shading规则只在assembly阶段生效,直接用sbt run不会应用shading,仍然会报错。
  • 用sbt dependencyTree命令确认Elastic4s依赖的ES具体版本,确保shading规则中的版本号和实际依赖一致。
  • 如果还有其他依赖ES客户端的第三方库,也要把它们加入对应的shading规则中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:32:28