flink “NoSuchFieldError: Companion“ okhttp冲突

1,639 阅读2分钟

解决 java.lang.NoSuchFieldError: Companion 报错指南

问题描述

在运行 Java 应用程序时,可能会遇到以下错误:

java.lang.NoSuchFieldError: Companion
    at okhttp3.internal.Util.<clinit>(Util.kt:71)
    at okhttp3.internal.concurrent.TaskRunner.<clinit>(TaskRunner.kt:309)
    at okhttp3.ConnectionPool.<init>(ConnectionPool.kt:41)
    at okhttp3.ConnectionPool.<init>(ConnectionPool.kt:47)
    at okhttp3.OkHttpClient$Builder.<init>(OkHttpClient.kt:471)

这个错误通常表明 okhttp3 库缺失或存在版本冲突。尽管代码中可能已经加载了 okhttp 包,或者 lib 目录中已经包含了这个包,但仍然可能出现此问题。

解决方案

1. 检查是否缺失 okhttp3 包

首先,确保项目中已经正确引入了 okhttp3 依赖。

  • Maven 项目:检查 pom.xml 文件,确保包含以下依赖:

    <dependency>
        <groupId>com.squareup.okhttp3</groupId>
        <artifactId>okhttp</artifactId>
        <version>4.x.x</version> <!-- 请使用最新稳定版本 -->
    </dependency>
    

    注意:okhttp3 自带 okio 依赖,因此不需要单独引入 okio

  • Flink 项目:如果使用 Flink,确保在 Flink 的 lib 目录中添加了 okhttp3 的 JAR 包。

2. 检查依赖冲突

依赖冲突是导致此错误的常见原因。使用 Maven 或 IntelliJ IDEA 的 Maven 插件检查依赖冲突。

  • 检查冲突来源

    • 多个 okhttp 或 okhttp3 版本冲突。
    • okhttp3 与 okio 版本不匹配。
  • 解决冲突

    • 在 pom.xml 中明确指定 okhttp3 的版本。
    • 确保 okhttp3 与 okio 版本相匹配。

image.png

3. 检查非 Flink JAR 包冲突

如果问题不是由 Flink JAR 包引起的,可能是其他 JAR 包中包含了冲突的 okhttp3 版本。

  • 步骤

    1. 将 Flink lib 目录及项目中的所有 JAR 包放在同一个 pom.xml 文件中,检查冲突来源。
    2. 解压可疑的 JAR 包,查看 com 目录下是否有 okhttp 的目录。如果有,则可以确定该包可能冲突。
    3. 从 GitHub 获取冲突包的源码,重新打包。

案例分享

笔者曾遇到类似问题,原因是 flink-shaded-hadoop-2-uber 包中包含了 okhttp。解决方案是下载 flink-shaded 10.0 版本并重新打包。注意,Flink 1.10 之后改变了与 Hadoop 的接入方式,因此不能选择最新版本的 flink-shaded 包。重新打包后,冲突问题得以解决。

总结

通过以上步骤,可以有效解决 java.lang.NoSuchFieldError: Companion 报错问题。关键在于确保 okhttp3 依赖正确引入,并解决可能存在的版本冲突。