解决 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版本相匹配。
- 在
3. 检查非 Flink JAR 包冲突
如果问题不是由 Flink JAR 包引起的,可能是其他 JAR 包中包含了冲突的 okhttp3 版本。
-
步骤:
- 将 Flink
lib目录及项目中的所有 JAR 包放在同一个pom.xml文件中,检查冲突来源。 - 解压可疑的 JAR 包,查看
com目录下是否有okhttp的目录。如果有,则可以确定该包可能冲突。 - 从 GitHub 获取冲突包的源码,重新打包。
- 将 Flink
案例分享
笔者曾遇到类似问题,原因是 flink-shaded-hadoop-2-uber 包中包含了 okhttp。解决方案是下载 flink-shaded 10.0 版本并重新打包。注意,Flink 1.10 之后改变了与 Hadoop 的接入方式,因此不能选择最新版本的 flink-shaded 包。重新打包后,冲突问题得以解决。
总结
通过以上步骤,可以有效解决 java.lang.NoSuchFieldError: Companion 报错问题。关键在于确保 okhttp3 依赖正确引入,并解决可能存在的版本冲突。