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>