www urlencoded library form java maven apache-httpclient-4.x unirest mashape

urlencoded - java.lang.NoSuchFieldError: org.apache.http.message.BasicLineFormatter.INSTANCE de Mashape Unirest en la aplicaciĆ³n Java



unirest java jar (5)

Tengo un proyecto Maven Java que usa Mashape Unirest para enviar solicitudes HTTP a otras URL. Actualmente estoy escribiendo una prueba de integración (usando TestNG ) que envía una solicitud HTTP normal usando Unirest. Cuando ejecuto la prueba de integración a través de Maven (a través del complemento Failsafe), la solicitud se envía con éxito. Sin embargo, cuando intento ejecutar la prueba de integración a través de Eclipse, sigo recibiendo el siguiente error:

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 ...

También puedo reproducir este error usando un script de aplicación Java básico.

Me he asegurado de que las dependencias que estoy usando en mi archivo pom.xml sean las más recientes y mejores, como se ve a continuación:

<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>

También revisé el código fuente de BasicLineFormatter.java , tanto del archivo fuente descargado a Eclipse como del repositorio Httpcore Github de Apache . En el repositorio Github, observe cómo se define el campo INSTANCE para la rama 4.3.x y la rama troncal, pero no en ramas más antiguas como 4.2.x. Sin embargo, de hecho estoy usando la versión 4.3.2 en mi proyecto, así que debería usar un archivo JAR para Httpcore que tenga la última versión de BasicLineFormatter . Sé que, en base a los archivos JAR de Maven Dependencies que están en mi proyecto, estoy usando las últimas versiones de estas dependencias de Apache, no las versiones anteriores especificadas como dependencias posteriores de mi proyecto.

He revisado otras publicaciones de SOF y blogs sobre este tema, como Mashape Unirest Java: java.lang.NoClassDefFoundError y esta publicación de blog también , pero todas parecen estar hablando de resolver el problema NoSuchFieldError para Android . Sin embargo, estoy tratando con una aplicación Java independiente, no una aplicación Android.

No sé cómo solucionar este problema. ¿Alguien tiene alguna idea de lo que tengo que hacer?

ACTUALIZAR

En lugar de mostrar mi caso de prueba, reduciré la ilustración de una reproducción de este problema a una simple aplicación Java de una línea, porque el problema existe con cualquier aplicación Java o caso de prueba ejecutado a través de Eclipse, no solo una prueba en particular:

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

Normalmente, esto debería imprimir el HTML de la página de inicio de Google, pero en su lugar obtengo el rastro de pila NoSuchFieldError.

¡FIJO!

El problema era que AWS SDK (está en mi classpath porque estoy desarrollando para Elastic Beanstalk) tenía un archivo JAR conflictivo. Utilizando la solución de Oleg (gracias por cierto), imprimí la siguiente salida en una prueba unitaria:

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

Tendré que reorganizar mi classpath para que AWS SDK ya no esté en conflicto.


Como ya se mencionó en comentarios anteriores, es principalmente debido a las versiones conflictivas de httpcore jar, el campo estático INSTANCE se ha agregado a la clase BasicLineFormatter en versions > 4.3.1 , aunque es posible que haya agregado la última versión del jar de httpcore en sus dependencias , pero es muy posible que otra versión (inferior) de jar se esté recogiendo.

Entonces, primero para confirmar que se está recogiendo el jar incorrecto, use la siguiente línea de código:

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

Si esto imprime, la versión inferior del jar, entonces se confirma que está escogiendo la versión inferior del jar de httpcore (puede ser de otras dependencias de su proyecto),

Solución -

Agregue las siguientes dependencias de maven / gradle en la parte superior de la lista de dependencias (o por encima de la otra dependencia del proyecto que causó el conflicto) -

<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>


La única explicación plausible para este problema es que existe una versión anterior de HttpCore en el classpath (a menos que también desee considerar la posibilidad de que los hombres verdes de Marte jueguen con su computadora remotamente desde un platillo volador).

Puede agregar este fragmento a su código para averiguar de qué jar se obtiene la clase. Esto podría ayudar a descubrir por qué ese jar está en su classpath en primer lugar.

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

Esto básicamente me dice que en mi caso el contenedor reside en el repositorio maven local y es probable que Maven lo haya agregado al classpath

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


Me enfrenté a la misma excepción al usar 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)

Y descubrió que se debía a DefaultConnectionKeepAliveStrategy.INSTANCE; y el apache-httpcomponents-httpclient.jar conflictivo era apache-httpcomponents-httpclient.jar en mi classpath. Agregar esta publicación para ayudar a cualquier persona que enfrenta una excepción similar


Recibí esta excepción: Caused by: java.lang.NoSuchFieldError: INSTANCE

Solución:

Esto sucede si tienes dos clases de versión diferentes en tu classpath ... [...], entonces primero encuentro esa clase (una versión de clase), hago clic en esa clase, selecciono la ruta de compilación , luego hago clic en eliminar de la ruta de compilación .


si está usando aws sdk, este error ocurre debido a una falta de coincidencia de la dependencia. Para evitar este error, haga lo siguiente: 1. Coloque las dependencias en el orden requerido aws sdk y el extremo preferiblemente 2.Agregue el complemento de sombra al proyecto.

Esto resolvió mi problema