ecb*_*die 36 java maven apache-httpclient-4.x unirest mashape
我有一个Maven Java项目,它使用Mashape Unirest将HTTP请求发送到其他URL.我目前正在编写一个使用Unirest发送普通HTTP请求的集成测试(使用TestNG).当我通过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 ...
Run Code Online (Sandbox Code Playgroud)
我还能够使用基本的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>
Run Code Online (Sandbox Code Playgroud)
我还检查了源代码BasicLineFormatter.java,包括从下载到Eclipse的源文件和Apache的Httpcore Github repo.在Github INSTANCE仓库中,注意如何为4.3.x分支和主干分支定义字段,但不在4.2.x之类的旧分支中定义.但是,我确实4.3.2在我的项目中使用了版本,因此我应该使用具有最新版本的Httpcore的JAR文件BasicLineFormatter.我知道,基于我项目中的Maven Dependencies 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());
Run Code Online (Sandbox Code Playgroud)
通常,这应该打印Google主页的HTML,但我得到NoSuchFieldError堆栈跟踪.
问题是AWS SDK(它在我的类路径上,因为我正在为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
Run Code Online (Sandbox Code Playgroud)
我将不得不重新安排我的类路径,以便AWS SDK不再发生冲突.
ok2*_*k2c 96
对这个问题唯一合理的解释是在类路径上有一个旧版本的HttpCore(除非你也想考虑一下火星上的绿人可能会从飞碟上远程搞乱你的电脑).
您可以将此代码段添加到代码中,以找出该类从中获取的jar.这可能有助于首先找出jar在你的类路径上的原因.
ClassLoader classLoader = MyClass.class.getClassLoader();
URL resource = classLoader.getResource("org/apache/http/message/BasicLineFormatter.class");
System.out.println(resource);
Run Code Online (Sandbox Code Playgroud)
这基本上告诉我,在我的情况下,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
Run Code Online (Sandbox Code Playgroud)
正如之前的评论已经提到的那样,主要是因为httpcorejar的版本冲突,静态字段INSTANCE已被添加到BasicLineFormatter类中versions > 4.3.1,虽然您可能已经httpcore在依赖项中添加了最新版本的jar,但它很可能是其他的(更低的)罐子的版本被拿起来.
所以,首先要确认,错误的罐子被拿起,使用以下代码行 -
ClassLoader classLoader = <Your Class>.class.getClassLoader();
URL resource = classLoader.getResource("org/apache/http/message/BasicLineFormatter.class");
System.out.println(resource);
Run Code Online (Sandbox Code Playgroud)
如果打印出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>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
54802 次 |
| 最近记录: |