19
java version "1.7.0_71" 
Gradle 2.1

Hello,

UPDATE:

The dependencies

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

Does this mean I have 4.1 that is a soft link to 4.3.3? Seems strange as when I print out what the class loader is loading it seems to load 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 seems very strange.

I keep getting this error when I try and run my httpClient. Everything compiles ok.

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

My code is very simple, removed not important code to keep it small:

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

The output I get from the classLoader is this:

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

I am using gradle as my build tool and have set the dependencies like this in my build.gradle file:

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

I have also tried to include the following httpcore, but still get the same error:

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

Everything builds ok, its only when I run my httpClient,

Many thanks for any suggestions,

ant2009
  • 27,094
  • 154
  • 411
  • 609
  • 1
    You may also have an older version of httpcore somewhere in your dependency tree. What is the output for `gradle dependencies`? – Ori Dar Jan 13 '15 at 11:46
  • 1
    Could You please provide a full, runnable example that illustrates the problem? – Opal Jan 13 '15 at 15:47
  • You have different httpcore versions in classpath. Try to exclude httpcore 4.1, looks like you have to do this 2 times with different jars. – user1516873 Jan 15 '15 at 16:15
  • Any plugin in your `build.gradle` ? Did you try to manually delete `.gradle/caches directory` ? – ToYonos Jan 15 '15 at 16:39
  • Any chance you are in an OSGi container? – Gábor Bakos Jan 15 '15 at 17:38
  • Most likely a conflicting jar file. see http://stackoverflow.com/questions/22330848/httpclient-example-exception-in-thread-main-java-lang-nosuchfielderror-inst and http://stackoverflow.com/questions/21864521/java-lang-nosuchfielderror-org-apache-http-message-basiclineformatter-instance – Balder Jan 16 '15 at 08:31
  • Could you add your gradle file ? – ToYonos Jan 16 '15 at 08:40
  • How are you running it? (Launch config in IDE, command line java, Etc) - this is key to understanding where your runtime classpath is coming from. – Ryan Jan 16 '15 at 16:46
  • Could you attach `gradle dependencies` without `grep` ? – lpiepiora Jan 18 '15 at 13:59
  • 6
    19x 500 bounties, and 1800 rep in about 10 other bounties... ant2009, you're probably the only person on SO I know of that has 60 gold, 185 silver & 320 brown badges, spent about 12k rep on bounties - and has 327 reputation... *THIS. IS. MADNESS!* –  Jan 19 '15 at 01:45
  • @ant2009, any chance you could answer the above questions ? – ToYonos Jan 20 '15 at 19:06
  • 1
    @ToYonos and vaxquie, Well, not sure what I am doing incorrect I use SO within the guidelines and policy of their regulations. I have been a member for a long time, and during that time I have posted questions and answered some as well. The 500 point bounties is to give extra credit for the support from other members. – ant2009 Jan 21 '15 at 06:34
  • I meant the other above questionS ;) – ToYonos Jan 21 '15 at 07:42
  • At the same point you do `ClassLoader classLoader = GenieClient.class.getClassLoader();` , do `ClassLoader formatterClassLoader = BasicLineFormatter.class.getClassLoader();` and `URL formatterResource = formatterClassLoader.getResource("org/apache/http/message/BasicLineFormatter.class");` check they match - i.e. that BasicLineFormatter is not being picked up from elsewhere at runtime (it feels like it must be as you're obviously picking the right one up at build time or this would be a compile error). If it identifies issue, I'll chuck it in an answer. – J Richard Snape Jan 22 '15 at 17:01
  • @ant2009 I never said it's incorrect or against the rules - I only expressed my utter astonishment with that fact... –  Oct 14 '15 at 12:54

5 Answers5

5

Start your jvm with -verbose:class, it will show which class is being loaded from where.

I had such problems in the past in two scenarios:

  1. one of the jars you're loading has a manifest with Classpath clause which references incorrect version of httpcore.

  2. you're running within some container (tomcat or sth) with own classloaders and some classes are loaded e.g. by the container from a different jar.

I also don't think your code showing resource for the class works as it explicitly uses GenieClient's classloader. Probably using BasicLineFormatter.class.getClassloader() would give different results. But better try with -verbose:class.

Marko
  • 20,385
  • 13
  • 48
  • 64
mabn
  • 2,473
  • 1
  • 26
  • 47
5

org.apache.httpcomponents:httpcore:4.1 -> 4.3.3 means 4.1 is the requested version, which is resolved to 4.3.3 by conflict resolution. Executing something like gradle -q dependencyInsight --configuration compile --dependency httpcore should give you more insight on this.

You should check the build output, and see what jars are actually packaged with your app. Also, using some file manager run a search for BasicLineFormatter.class through the build output (including archives, of course), this should give you a definite answer what jars contain what version of this class.

If there is only one version (4.3.3) this must mean that the other version comes from the container that's running your app. Ways of resolving this depend on the container.

If you do find multiple versions, you can try excluding transitive dependency to httpcore globally in the project (chapter 51.4.7 of user guide).

If you define an exclude for a particular configuration, the excluded transitive dependency will be filtered for all dependencies when resolving this configuration or any inheriting configuration.

Predrag Maric
  • 23,938
  • 5
  • 52
  • 68
5

Seems like BasicLineFormatter got its static INSTANCE in 4.3-beta1 link and link

atish shimpi
  • 4,873
  • 2
  • 32
  • 50
2

Clearly there is some older version of BasicLineFormatter on your classpath, one that has the DEFAULT field instead of INSTANCE. See e.g.

But your classloader is reporting that you're using httpcore-4.3.3, and your Gradle dependency tree backs that up.

So it seems that you have some other JAR that has an old version of BasicLineFormatter in it. You might need to go through your dependency JARs and just look to see whether it is in there. Try a jar tf *.jar | grep 'BasicLineFormatter' to see which JARs might be involved.

Also, this may be relevant. I looked at your tags and it seems you do some Android development. So the following Stack Overflow question may be of interest:

Even if that's not the exact issue, it shows how you might have an old BasicLineFormatter hanging around even if you have the right httpcore dependency.

Community
  • 1
  • 1
2
  1. find httpcore which is of an older version than 4.3
  2. remove the older version of httpcore jar from Referenced Libraries.
Saurabh Saha
  • 962
  • 11
  • 18