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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21864521/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 11:08:17  来源:igfitidea点击:

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

javamavenapache-httpclient-4.xunirestmashape

提问by ecbrodie

I have a Maven Java project that uses Mashape Unirestfor sending HTTP requests to other URLs. I am currently writing an integration test (using TestNG) that sends a normal HTTP request using Unirest. When I run the integration test through Maven (via the Failsafe plugin), the request is sent out successfully. However, when I try to run the integration test via Eclipse, I keep on getting the following error:

我有一个 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 ...

I am also able to reproduce this error using a basic Java application script.

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

I have made sure that the dependencies I am using in my pom.xmlfile are the latest and greatest, as seen below:

我已确保我在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>

I have also checked out the source code of BasicLineFormatter.java, both from the source file downloaded to Eclipse and from Apache's Httpcore Github repo. In the Github repo, notice how the INSTANCEfield is defined for the 4.3.x branch and the trunk branch, but not in older branches like 4.2.x. However, I am indeed using version 4.3.2in my project, so I should be using a JAR file for Httpcore that has the latest version of BasicLineFormatter. I know that, based on the Maven Dependencies JAR files that are in my project, that I am indeed using the latest versions of these Apache dependencies, not the older versions specified as downstream dependencies of my project.

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

I have checked other various SOF and blog posts about this issue, such as Mashape Unirest Java : java.lang.NoClassDefFoundErrorand this blog post too, but they all seem to be talking about solving the NoSuchFieldError problem for Android. However, I'm dealing with a standalone Java application, not an Android application.

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

I am at a loss in determining how to troubleshoot this issue. Anyone have any idea what I need to do?

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

UPDATE

更新

Instead of showing my test case, I will reduce the illustration of a reproduction of this problem to just a simple one-liner Java application, because the problem exists with any Java application or test case run through Eclipse, not just one particular test:

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

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

Normally, this should print the HTML of the Google home page, but I instead get the NoSuchFieldError stack trace.

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



FIXED!

固定的!

The problem was that the AWS SDK(it's on my classpath because I'm developing for Elastic Beanstalk) had a conflicting JAR file. Using Oleg's solution (thanks BTW), I printed the following output in a unit test:

问题是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

I'll have to rearrange my classpath so that AWS SDK is no longer conflicting.

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

采纳答案by ok2c

The only plausible explanation to this problem is there is an older version of HttpCore on the classpath (unless you also want to consider a possibility of green men from Mars messing with your computer remotely from a flying saucer).

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

You can add this snippet to your code to find out what jar the class gets picked up from. This might help find out why that jar is on your classpath in the first place.

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

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

This basically tells me that in my case the jar resides in the local maven repository and likely to have been added to the classpath by Maven

这基本上告诉我,在我的情况下,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

回答by Nivedita Dixit

I faced the same exception using unirest:

我在使用 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)

And found it was due to DefaultConnectionKeepAliveStrategy.INSTANCE;and the conflicting jar was apache-httpcomponents-httpclient.jarin my classpath. Adding this post to help anyone who faces similar exception

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

回答by vijay m p

I got this Exception: Caused by: java.lang.NoSuchFieldError: INSTANCE

我得到了这个例外: Caused by: java.lang.NoSuchFieldError: INSTANCE

Solution:

解决方案:

This happens if you have two different version classes in your classpath…. […], So I first find that class (one version of class), click that class, select build path, then I click remove from build path.

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

回答by Anand Immannavar

As already mentioned by previous comments, It's mainly because of the conflicting versions of httpcorejar, the static field INSTANCE is been added to BasicLineFormatterclass in versions > 4.3.1, Though you might have added the latest version of the httpcorejar in your dependencies, but its highly possible that other (lower) version of jar is getting picked up.

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

So, first to confirm that, wrong jar is getting picked up, Use the following line of code -

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

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

If this prints, the lower version of the jar, then it's confirmed that it's picking the lower version of the httpcore jar (May be from other dependencies of your project),

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

Solution -

解决方案 -

Add following maven/gradle dependencies at the top of dependency list (Or above the other project dependency which caused the conflict) -

在依赖列表的顶部添加以下 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>

回答by SamsonFrancis

if you are using aws sdk this error occurs because of dependency mismatch. To avoid this error do the following: 1.Put the dependecies in the required order aws sdk and the end preferably 2.Add shade plugin to the project

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

This solved my problem

这解决了我的问题