我有一个 Maven Java 项目,它使用Mashape Unirest http://unirest.io/java.html用于向其他 URL 发送 HTTP 请求。我目前正在编写集成测试(使用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>
我还查看了源代码BasicLineFormatter.java
,既来自下载到 Eclipse 的源文件,也来自Apache 的 Httpcore Github 存储库 https://github.com/apache/httpcore/blob/4.3.x/httpcore/src/main/java/org/apache/http/message/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 https://stackoverflow.com/questions/19562984/mashape-unirest-java-java-lang-noclassdeffounderror and 这篇博文也是 http://blog.mashape.com/post/69639276345/using-unirest-java-for-your-android-projects,但他们似乎都在谈论解决 NoSuchFieldError 问题Android。但是,我正在处理一个独立的 Java 应用程序,而不是 Android 应用程序。
我不知道如何解决这个问题。有人知道我需要做什么吗?
UPDATE
我不会展示我的测试用例,而是将此问题的重现简化为一个简单的单行 Java 应用程序,因为通过 Eclipse 运行的任何 Java 应用程序或测试用例都存在该问题,而不仅仅是一个特定的测试:
System.out.println(Unirest.get("http://www.google.com").asStringAsync().get().getBody());
通常,这应该打印 Google 主页的 HTML,但我得到的是 NoSuchFieldError 堆栈跟踪。
FIXED!
问题是AWS SDK(它位于我的类路径上,因为我正在为 Elastic Beanstalk 进行开发)有一个冲突的 JAR 文件。使用奥列格的解决方案(感谢顺便说一句),我在单元测试中打印了以下输出:
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 SDK 不再发生冲突。