web-dev-qa-db-fra.com

NoSuchFieldError INSTANCE sur org.Apache.http.impl.io.DefaultHttpRequestWriterFactory

Java version "1.7.0_71" 
Gradle 2.1

Bonjour,

UPDATE:

Les dépendances

gradle dependencies | grep httpcore
|    +--- org.Apache.httpcomponents:httpcore:4.3.3
|    +--- org.Apache.httpcomponents:httpcore:4.3.3
|    +--- org.Apache.httpcomponents:httpcore:4.3.3
|    +--- org.Apache.httpcomponents:httpcore:4.3.3
|    |         |    |         |    +--- org.Apache.httpcomponents:httpcore:4.1 -> 4.3.3
|    +--- org.Apache.httpcomponents:httpcore:4.3.3
|    |         |    |         |    +--- org.Apache.httpcomponents:httpcore:4.1 -> 4.3.3

Est-ce à dire que j'ai 4.1 qui est un lien logiciel vers 4.3.3? Cela semble étrange car lorsque j'imprime ce que le chargeur de classe charge, il semble charger 4.3.3: /home/steve/.gradle/caches/modules-2/files-2.1/org.Apache.httpcomponents/httpcore/4.3.3/f91b7a4aadc5cf486df6e4634748d7dd7a73f06d/httpcore-4.3.3.jar semble très étrange.

Je reçois toujours cette erreur lorsque j'essaie d'exécuter mon httpClient. Tout se compile bien.

Java.lang.NoSuchFieldError: INSTANCE
        at org.Apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.Java:52

Mon code est très simple, le code n'est pas important pour le garder petit:

public class GenieClient {
    private CloseableHttpClient mClient;

    public GenieClient() {
        ClassLoader classLoader = GenieClient.class.getClassLoader();
        URL resource = classLoader.getResource("org/Apache/http/message/BasicLineFormatter.class");
        log.log(Level.INFO, "resource: " + resource);

        mClient = HttpClientBuilder.create().build();
    }

    public int sendRequest() {   
        int responseCode = -1;

        try {
            HttpResponse response = mClient.execute(new HttpPost("http://www.google.com"));
            responseCode = response.getStatusLine().getStatusCode();
        }
        catch(IOException ex) {
            log.log(Level.SEVERE, "IOException: " + ex.getMessage());
        }

        return responseCode;
    }
}

La sortie que j'obtiens du classLoader est la suivante:

INFO: resource: jar:file:/home/steve/.gradle/caches/modules-2/files-2.1/org.Apache.httpcomponents/httpcore/4.3.3/f91b7a4aadc5cf486df6e4634748d7dd7a73f06d/httpcore-4.3.3.jar!/org/Apache/http/message/BasicLineFormatter.class

J'utilise gradle comme outil de construction et j'ai défini les dépendances comme ceci dans mon build.gradle fichier:

dependencies {
    compile 'org.Apache.httpcomponents:httpclient:4.3.6'
}

J'ai également essayé d'inclure le httpcore suivant, mais j'obtiens toujours la même erreur:

compile 'org.Apache.httpcomponents:httpcore:4.4'

Tout se passe bien, ce n'est que lorsque je lance mon httpClient,

Merci beaucoup pour toutes suggestions,

19
ant2009

org.Apache.httpcomponents:httpcore:4.1 -> 4.3.3 veux dire 4.1 est la version demandée, qui est résolue en 4.3.3 par résolution de conflits. Exécuter quelque chose comme gradle -q dependencyInsight --configuration compile --dependency httpcore devrait vous donner plus d'informations à ce sujet.

Vous devez vérifier la sortie de la génération et voir quels fichiers sont réellement fournis avec votre application. En outre, à l'aide d'un gestionnaire de fichiers, lancez une recherche sur BasicLineFormatter.class grâce à la sortie de la compilation (y compris les archives, bien sûr), cela devrait vous donner une réponse définitive sur les pots contenant quelle version de cette classe.

S'il n'y a qu'une seule version (4.3.3), cela doit signifier que l'autre version provient du conteneur qui exécute votre application. Les moyens de résoudre cela dépendent du conteneur.

Si vous trouvez plusieurs versions, vous pouvez essayer d'exclure la dépendance transitive à httpcore globalement dans le projet (chapitre 51.4.7 de guide de l'utilisateur ).

Si vous définissez une exclusion pour une configuration particulière, la dépendance transitive exclue sera filtrée pour toutes les dépendances lors de la résolution de cette configuration ou de toute configuration héritée.

5
Predrag Maric

Démarrez votre jvm avec -verbose: class, il montrera quelle classe est chargée depuis où.

J'ai eu de tels problèmes dans le passé dans deux scénarios:

  1. l'un des fichiers JAR que vous chargez a un manifeste avec la clause Classpath qui fait référence à une version incorrecte de httpcore.

  2. vous exécutez dans un conteneur (Tomcat ou sth) avec vos propres chargeurs de classe et certaines classes sont chargées, par exemple par le récipient d'un pot différent.

Je ne pense pas non plus que votre code montrant la ressource pour la classe fonctionne car il utilise explicitement le chargeur de classe de GenieClient. L'utilisation de BasicLineFormatter.class.getClassloader() donnerait probablement des résultats différents. Mais mieux vaut essayer avec -verbose:class.

5
mabn

On dirait que BasicLineFormatter a son statique INSTANCE in 4.3-beta1lien et lien

4
atish shimpi
  1. trouver httpcore qui est d'une version plus ancienne que 4.3
  2. supprimer l'ancienne version du pot httpcore des bibliothèques référencées.
2
Saurabh Saha

Il y a clairement une ancienne version de BasicLineFormatter sur votre chemin de classe, une qui a le champ DEFAULT au lieu de INSTANCE. Voir par exemple .

Mais votre chargeur de classe signale que vous utilisez httpcore-4.3.3, et votre arbre de dépendance Gradle le sauvegarde.

Il semble donc que vous ayez un autre JAR contenant une ancienne version de BasicLineFormatter. Vous devrez peut-être passer en revue vos fichiers JAR de dépendance et voir simplement s'ils s'y trouvent. Essayez un jar tf *.jar | grep 'BasicLineFormatter' pour voir quels fichiers JAR pourraient être impliqués.

En outre, cela peut être pertinent. J'ai regardé vos balises et il semble que vous fassiez du Android. Donc, le débordement de pile suivant question peut être intéressant:

Même si ce n'est pas le problème exact, cela montre comment vous pourriez avoir un vieux BasicLineFormatter qui traîne même si vous avez la bonne dépendance httpcore.

2
Willie Wheeler