0
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@Import({ JerseyConfig.class })
public class BenchApplicationTest {

@Autowired
private TestRestTemplate restTemplate;

@Test
public void contextLoads() {

    ResponseEntity<String> entity = this.restTemplate.getForEntity("/bench/healthcheck", String.class);
    assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);

  }

}

My application executes perfectly and i am able to test the api using Postman. But when i try the above method to execute the test case to test the API, it gives the following error.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testRestTemplate': Initialization of bean failed; nested exception is java.lang.NoSuchFieldError: INSTANCE
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
.....
Caused by: java.lang.NoSuchFieldError: INSTANCE
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.<clinit>(SSLConnectionSocketFactory.java:144) ~[httpclient-4.5.2.jar:4.5.2]
at org.apache.http.impl.client.HttpClientBuilder.build(HttpClientBuilder.java:962) ~[httpclient-4.5.2.jar:1.2.2]

I have tried to check the this error and the almost all of them suggest (like this link and link,) that there are multiple version of a jars(http-client/http-core) in my application. I have checked and i did not find multiple version of SSLConnectionSocketFactory in my application. If at all there are conflicting jars, how can i know which are conflicting. I do not manually add the jar, its a maven project. I am stuck with this problem for the last 1 week and I am now at my wits end.

Please find below my pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.2.RELEASE</version>
</parent>
<dependencies>
    <!-- Spring dependencies -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jersey</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jetty</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.18.1</version>
    </dependency>
    <dependency>
        <groupId>org.antlr</groupId>
        <artifactId>antlr-complete</artifactId>
        <version>3.5.2</version>
    </dependency>
    <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
    </dependency>
    <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.3.2</version>
    </dependency>
    <dependency>
        <groupId>commons-collections</groupId>
        <artifactId>commons-collections</artifactId>
    </dependency>
    <dependency>
        <groupId>commons-validator</groupId>
        <artifactId>commons-validator</artifactId>
        <version>1.4.1</version>
    </dependency>

    <dependency>
        <groupId>com.sun.jersey.contribs</groupId>
        <artifactId>jersey-multipart</artifactId>
        <version>1.19.3</version>
    </dependency>
    <dependency>
        <groupId>net.sf.json-lib</groupId>
        <artifactId>json-lib</artifactId>
        <version>2.4</version>
    </dependency>
    <dependency>
        <groupId>org.jsoup</groupId>
        <artifactId>jsoup</artifactId>
        <version>1.7.2</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
    </dependency>
    <dependency>
        <groupId>org.antlr</groupId>
        <artifactId>antlr-complete</artifactId>
        <version>3.5.2</version>
    </dependency>
    <dependency>
        <groupId>com.rabbitmq</groupId>
        <artifactId>amqp-client</artifactId>
        <version>2.8.6</version>
    </dependency>
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-all</artifactId>
        <version>1.9.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc6</artifactId>
        <version>11.2.0.4</version>
    </dependency>
    <dependency>
        <groupId>org.owasp.esapi</groupId>
        <artifactId>esapi</artifactId>
        <version>2.1.0</version>
    </dependency>
    <dependency>
        <groupId>com.sun.mail</groupId>
        <artifactId>javax.mail</artifactId>
    </dependency>
    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-jcs-jcache</artifactId>
        <version>2.0-beta-1</version>
    </dependency>
    <dependency>
        <groupId>org.reflections</groupId>
        <artifactId>reflections</artifactId>
        <version>0.9.9</version>
    </dependency>
    <dependency>
        <groupId>com.codahale.metrics</groupId>
        <artifactId>metrics-healthchecks</artifactId>
        <version>3.0.1</version>
    </dependency>
    <dependency>
        <groupId>com.googlecode.json-simple</groupId>
        <artifactId>json-simple</artifactId>
    </dependency>
</dependencies>

Any Help would be appreciated.

1 Answers1

1

Quick answer

Quick check of your pom.xml shows that particular dependency org.owasp.esapi:esapi pulls old 3.1 version of httpclient in. Try adding exclusion section to this dependency as described below. If this does not help, work through dependency tree accordingly

Full answer

Run the following command under your project root folder

mvn dependency:tree -Dincludes=commons-httpclient

That will print your project's maven dependency tree with all pulled transitive dependencies with artifact id commons-httpclient, for example:

[INFO] your:project:jar:1.0-SNAPSHOT
[INFO] \- org.owasp.esapi:esapi:jar:2.1.0:compile
[INFO]    \- org.owasp.antisamy:antisamy:jar:1.4.3:compile
[INFO]       \- commons-httpclient:commons-httpclient:jar:3.1:compile

Than you could determine what is the source of wrong version of httpclient coming in (for our example let it be org.owasp.esapi:esapi) and then you can exclude that transitive dependency implicitly by amending your pom.xml:

        <dependency>
            <groupId>org.owasp.esapi</groupId>
            <artifactId>esapi</artifactId>
            <version>2.1.0</version>
            <!-- change starts here -->
            <exclusions>
                <exclusion>
                    <groupId>commons-httpclient</groupId>
                    <artifactId>commons-httpclient</artifactId>
                </exclusion>
            </exclusions>
            <!-- change ends here -->
        </dependency>

Note, that you may require to filter dependency tree using wildcards like

mvn dependency:tree -Dincludes=*http*

or even work through plain tree output calling mvn dependency:tree without params

And finally you can end up with explicit adding required dependency to your pom.xml having wrong versions found and excluded as decried above:

<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
  <version>4.5.2</version>
</dependency>

Update

As problem is not resolved by above. Handy code piece to determine all the files being loaded from classpath:

ClassLoader cl = ClassLoader.getSystemClassLoader();

URL[] urls = ((URLClassLoader)cl).getURLs();

for(URL url: urls){
    System.out.println(url.getFile());
}

Can you put it into your contextLoads() right before restTemplate call and check/share the console output then?

Kostiantyn
  • 1,856
  • 11
  • 13
  • I followed your suggestions... i removed the other transitive relations for httpclient and explicitly defined the httpclient as you suggested... but still the problem persists.. The same error – Gouravmoy Mohanty Aug 31 '17 at 15:11
  • There can be a case when dependencies are not correctly downloaded for some reason, and that's why exclusion might not be picked up by maven correctly. Please try cleaning local repository (note: it will entirely remove maven local repo!) by using `mvn dependency:purge-local-repository` followed by `mvn clean buld` to re-download jars again – Kostiantyn Aug 31 '17 at 16:20
  • By the way, can you please double-check there is no **IDE-added** dependencies to your test classpath? I.e. some JARs imported through IDE capabilities to your project not via maven? Kind of global libraries or something like that – Kostiantyn Aug 31 '17 at 16:25
  • I am sure of it.. i have removed the other transitive jars... In the dependency hierarchy, there is only one jar - httpclient:4.5.2 after httpclient filter. Also i tried a clean and build... Same error Check the screenshot of the dependency tree filtered for "http" [link](http://imgur.com/a/iJCLl) – Gouravmoy Mohanty Aug 31 '17 at 17:17
  • I've added 'update' section with description of how to print all the test classpath jars to the console in order to see what httpclient jars are in place de facto. Can you please try it and share console output via [pastebin](https://pastebin.com/)? – Kostiantyn Aug 31 '17 at 19:44
  • Sorry for the delayed response. Please find the output in this [link](https://pastebin.com/iH6wKPHc). Also even though i comment Autowired private TestRestTemplate restTemplate;, it gives the same error. Only when i remove webEnvironment = WebEnvironment.RANDOM_PORT from the @SpringBootTest annotation, then i am able to run the contextLoad() with the classpath code you sent. – Gouravmoy Mohanty Sep 01 '17 at 09:35
  • Hmm... Looks like you've stripped the console output to have only 'm2' lines as I don't see any other entries like `/target/classes/`, JDK jars, etc. But that printing exercise itself has the goal of identifying non-maven classpath entries which could interfere with http client. – Kostiantyn Sep 01 '17 at 10:01
  • By the way, what happens to your test if you will keep in place `@SpringBootTest(...)` but comment out the `@Import({ JerseyConfig.class })` ? – Kostiantyn Sep 01 '17 at 10:01
  • Same error if i comment out Jersey Config Import. I am now taking a different approach. Instead of testing the API's within the app, i am now thinking a separate project and keeping all the API test code there. Anyway, i think the way you have suggested is correct but it still did not work for me. Maybe some configuration problem in my project. If the way you suggested works for anyone else, i will mark you answer as the correct answer. Thanks for the help :) – Gouravmoy Mohanty Sep 01 '17 at 11:10