繁体   English   中英

java.lang.NoSuchFieldError: org.apache.http.message.BasicLineFormatter.INSTANCE 来自 Java 应用程序中的 Mashape Unirest

[英]java.lang.NoSuchFieldError: org.apache.http.message.BasicLineFormatter.INSTANCE from Mashape Unirest in Java application

我有一个 Maven Java 项目,它使用Mashape Unirest将 HTTP 请求发送到其他 URL。 我目前正在编写一个集成测试(使用TestNG ),它使用 Unirest 发送一个普通的 HTTP 请求。 当我通过 Maven(通过 Failsafe 插件)运行集成测试时,请求被成功发送。 但是,当我尝试通过 Eclipse 运行集成测试时,我不断收到以下错误:

FAILED: getCurrentTimeTest
java.lang.NoSuchFieldError: INSTANCE
    at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:52)
    at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:56)
    at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<clinit>(DefaultHttpRequestWriterFactory.java:46)
    at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<init>(ManagedHttpClientConnectionFactory.java:72)
    at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<init>(ManagedHttpClientConnectionFactory.java:84)
    at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<clinit>(ManagedHttpClientConnectionFactory.java:59)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$InternalConnectionFactory.<init>(PoolingHttpClientConnectionManager.java:487)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:147)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:136)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:112)
    at org.apache.http.impl.client.HttpClientBuilder.build(HttpClientBuilder.java:726)
    at com.mashape.unirest.http.options.Options.refresh(Options.java:41)
    at com.mashape.unirest.http.options.Options.<clinit>(Options.java:27)
    at com.mashape.unirest.http.HttpClientHelper.prepareRequest(HttpClientHelper.java:141)
    at com.mashape.unirest.http.HttpClientHelper.requestAsync(HttpClientHelper.java:80)
    at com.mashape.unirest.request.BaseRequest.asStringAsync(BaseRequest.java:56)
    at ...

我还可以使用基本的 Java 应用程序脚本重现此错误。

我已确保我在pom.xml文件中使用的依赖项是最新和最大的,如下所示:

<dependency>
    <groupId>com.mashape.unirest</groupId>
    <artifactId>unirest-java</artifactId>
    <version>1.3.5</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.3.2</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpasyncclient</artifactId>
    <version>4.0</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpmime</artifactId>
    <version>4.3.2</version>
</dependency>
<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20140107</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpcore</artifactId>
    <version>4.3.2</version>
</dependency>

我还从下载到 Eclipse 的源文件和Apache 的 Httpcore Github repo 中查看了BasicLineFormatter.java的源代码。 在 Github 存储库中,注意INSTANCE字段是如何为 4.3.x 分支和主干分支定义的,而不是在像 4.2.x 这样的旧分支中定义的。 但是,我确实在我的项目中使用了4.3.2版本,所以我应该为 Httpcore 使用一个 JAR 文件,它具有最新版本的BasicLineFormatter 我知道,基于我项目中的 Maven 依赖项 JAR 文件,我确实使用了这些 Apache 依赖项的最新版本,而不是指定为我项目下游依赖项的旧版本。

我已经检查了有关此问题的其他各种 SOF 和博客文章,例如Mashape Unirest Java : java.lang.NoClassDefFoundError这篇博客文章,但它们似乎都在谈论解决Android的 NoSuchFieldError 问题。 但是,我正在处理一个独立的 Java 应用程序,而不是一个 Android 应用程序。

我不知道如何解决这个问题。 任何人都知道我需要做什么?

更新

我将不再展示我的测试用例,而是将这个问题的再现简化为一个简单的单行 Java 应用程序,因为任何 Java 应用程序或通过 Eclipse 运行的测试用例都存在问题,而不仅仅是一个特定的测试:

System.out.println(Unirest.get("http://www.google.com").asStringAsync().get().getBody());

通常,这应该打印 Google 主页的 HTML,但我得到的是 NoSuchFieldError 堆栈跟踪。


固定的!

问题是AWS 开发工具包(它在我的类路径上,因为我正在为 Elastic Beanstalk 开发)有一个冲突的 JAR 文件。 使用 Oleg 的解决方案(感谢 BTW),我在单元测试中打印了以下输出:

jar:file:/some/path/aws-java-sdk/1.7.1/third-party/httpcomponents-client-4.2.3/httpcore-4.2.jar!/org/apache/http/message/BasicLineFormatter.class

我必须重新安排我的类路径,以便 AWS 开发工具包不再发生冲突。

对这个问题唯一合理的解释是类路径上有一个旧版本的 HttpCore(除非你还想考虑来自火星的绿人从飞碟远程弄乱你的计算机的可能性)。

您可以将此代码段添加到您的代码中,以找出该类是从哪个 jar 中提取的。 这可能有助于找出为什么那个 jar 首先出现在您的类路径上。

ClassLoader classLoader = MyClass.class.getClassLoader();
URL resource = classLoader.getResource("org/apache/http/message/BasicLineFormatter.class");
System.out.println(resource);

这基本上告诉我,在我的情况下,jar 驻留在本地 Maven 存储库中,并且可能已被 Maven 添加到类路径中

jar:file:/home/oleg/.m2/repository/org/apache/httpcomponents/httpcore/4.3.1/httpcore-4.3.1.jar!/org/apache/http/message/BasicLineFormatter.class

正如之前的评论已经提到的,这主要是因为httpcore jar 的版本冲突,静态字段 INSTANCE 在versions > 4.3.1被添加到BasicLineFormatter类中,尽管您可能已经在依赖项中添加了最新版本的httpcore jar ,但很有可能其他(较低)版本的 jar 正在被接受。

所以,首先要确认,错误的 jar 被拿起,使用以下代码行 -

ClassLoader classLoader = <Your Class>.class.getClassLoader();
URL resource = classLoader.getResource("org/apache/http/message/BasicLineFormatter.class");
System.out.println(resource);

如果打印出较低版本的 jar,则确认它正在选择较低版本的 httpcore jar(可能来自您项目的其他依赖项),

解决方案 -

在依赖列表的顶部添加以下 maven/gradle 依赖(或在导致冲突的其他项目依赖之上) -

<dependency>
     <groupId>com.mashape.unirest</groupId>
     <artifactId>unirest-java</artifactId>
     <version>1.4.5</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpcore</artifactId>
    <version>4.4.1</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.4.1</version>
</dependency>

我在使用 unirest 时遇到了同样的异常:

java.lang.NoSuchFieldError: INSTANCE
        at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:52)
at com.mashape.unirest.http.options.Options.refresh(Options.java:55)
at com.mashape.unirest.http.options.Options.<clinit>(Options.java:36)

发现是由于DefaultConnectionKeepAliveStrategy.INSTANCE; 并且冲突的 jar 是我的类路径中的apache-httpcomponents-httpclient.jar 添加此帖子以帮助任何面临类似异常的人

我得到了这个异常: Caused by: java.lang.NoSuchFieldError: INSTANCE

解决方案:

如果您的类路径中有两个不同的版本类,就会发生这种情况...... […],所以我首先找到那个类(一个版本的类),点击那个类,选择build path ,然后我点击remove from build path

如果您使用的是 aws sdk,则会由于依赖项不匹配而发生此错误。 为避免此错误,请执行以下操作: 1. 将依赖项按所需的顺序 aws sdk 和结尾最好 2. 将 shade 插件添加到项目

这解决了我的问题

你可以参考我的回答
HTTPClient 示例 - 线程“main”中的异常 java.lang.NoSuchFieldError: INSTANCE


我的情况是我的类路径中有httpclient-4.4.1.jar和 httpcore-4.4.1.jar ,
但JVM加载BasicLineFormatter的HttpCore-4.0.jar

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM