Archive for the 'Maven' Category

Avoid “java.net.BindException: Address already in use” in test cases

A common problem when you are running integration test is the “java.net.BindException: Address already in use”. The cause of this issue is you are using a fixed port to run embedded servers, like:

<jaxws:endpoint id="classImpl"     
     implementor="org.apache.cxf.jaxws.service.Hello"
     endpointName="e:HelloEndpointCustomized"
     serviceName="s:HelloServiceCustomized"
     address="http://localhost:9000/test"
     xmlns:e="http://service.jaxws.cxf.apache.org/endpoint"
     xmlns:s="http://service.jaxws.cxf.apache.org/service">

If the port (9000 in the above example) is used by another service, you will get an exception:

java.lang.IllegalStateException: Failed to load ApplicationContext
     Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'classImpl': Invocation of init method failed; nested exception is javax.xml.ws.WebServiceException: org.apache.cxf.interceptor.Fault: Could not start Jetty server on port 9,000: Address already in use
     Caused by: javax.xml.ws.WebServiceException: org.apache.cxf.interceptor.Fault: Could not start Jetty server on port 9,000: Address already in use
     Caused by: org.apache.cxf.interceptor.Fault: Could not start Jetty server on port 9,000: Address already in use
     Caused by: java.net.BindException: Address already in use

To solve this problem, specially for CI (continuous integration) environments, you have to externalize the port value:

<jaxws:endpoint id="classImpl"     
     implementor="org.apache.cxf.jaxws.service.Hello"     
     endpointName="e:HelloEndpointCustomized"     
     serviceName="s:HelloServiceCustomized"     
     address="http://localhost:${servicePort}/test"     
     xmlns:e="http://service.jaxws.cxf.apache.org/endpoint"     
     xmlns:s="http://service.jaxws.cxf.apache.org/service"/>

Then, set it dynamically, when your test is starting, like:

import org.junit.BeforeClass;
import org.apache.camel.test.AvailablePortFinder;

public class IntegrationTest {

     @BeforeClass
     public static void configure() {
          System.setProperty("servicePort", String.valueOf(AvailablePortFinder.getNextAvailable()));
     }

}

Be sure to have the camel-test jar in your classpath. By using maven, you can achieve this with a dependency like:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-test</artifactId>
    <version>2.18.1</version>
    <scope>test</scope>
</dependency>

Cobertura in SonarQube with Jenkins and JaCoCo for Maven Multi-Module Projects

There is a typical issue when you try to analyze a Maven multi-module project in SonarQube: the cobertura reports are lost. So, when using Jenkins you have to configure your job with:

  • In the build section, use:
clean org.jacoco:jacoco-maven-plugin:prepare-agent install -Dmaven.test.failure.ignore=true -Djacoco.destFile=${WORKSPACE}/target/jacoco.exe

1

  • In the Post Steps, use a “Execute SonarQube Scanner” with:
sonar.jacoco.reportPath=${WORKSPACE}/target/jacoco.exec

2.png

The first configuration allows that all executions of JaCoCo maven plugin publish the results in the same file (by default it appends the results). The second one, tells to SonarQube where to find the JaCoCo results.


Enhanced Links