У меня есть проект Maven Java, который использует Mashape Unirest для отправки HTTP-запросов на другие URL-адреса. В настоящее время я пишу интеграционный тест (используя TestNG), который отправляет обычный HTTP-запрос с использованием Unirest. Когда я запускаю интеграционный тест через 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-приложение script.
Я убедился, что зависимости, которые я использую в моем файле 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 repo, В репозитории Github обратите внимание, как поле INSTANCE
определено для ветки 4.3.x и ветки соединительной линии, но не в старых ветвях, таких как 4.2.x. Тем не менее, я действительно использую версию 4.3.2
в своем проекте, поэтому я должен использовать JAR файл для Httpcore с последней версией BasicLineFormatter
. Я знаю, что на основе файлов JAR Maven Dependencies, которые находятся в моем проекте, я действительно использую последние версии этих зависимостей Apache, а не более старые версии, указанные как нисходящие зависимости моего проекта.
Я проверил другие сообщения SOF и блога об этой проблеме, такие как Mashape Unirest Java: java.lang.NoClassDefFoundError и это сообщение в блоге тоже, но все они, похоже, говорят о решении проблемы NoSuchFieldError для Android. Тем не менее, я имею дело с автономным Java-приложением, а не с Android-приложением.
Я затрудняюсь определить, как устранить эту проблему. Кто-нибудь знает, что мне нужно делать?
UPDATE
Вместо того, чтобы показывать мой тестовый пример, я уменьшу иллюстрацию воспроизведения этой проблемы до простого однострочного Java-приложения, поскольку проблема существует с любым Java-приложением или тестовым сценарием, выполняемым через Eclipse, а не только с одним конкретным тест:
System.out.println(Unirest.get("http://www.google.com").asStringAsync().get().getBody());
Обычно это должно печатать HTML-страницы главной страницы Google, но вместо этого я получаю трассировку стека NoSuchFieldError.
ИСПРАВЛЕНО!
Проблема заключалась в том, что AWS SDK (он на моем пути к классам, потому что я разрабатываю для Elastic Beanstalk) имел противоречивый JAR файл. Используя решение Oleg (спасибо BTW), я напечатал следующий вывод в unit test:
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 больше не противоречил.