Archive for the 'Java' 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.

Inspect in-memory Hsqldb database

In Java, it is common to use in-memory databases for testing proposes. Hsqldb (http://hsqldb.org/) is a great alternative to this. But, what’s happen if your test fail? In some cases, is necessary to inspect the database contents to ensure everything goes right. So, how can we do that?

Suppose that your database configuration is like:

Connection c =
DriverManager.getConnection("jdbc:hsqldb:mem:testdb", "sa", "");

First, make sure to set a breakpoint at the specific line of your code that you want to inspect. Then, you have to run the “database inspector”:

org.hsqldb.util.DatabaseManagerSwing.main(
  new String[] { "--url", "jdbc:hsqldb:mem:testdb",
    "--user", "sa", "--password", ""});

There are two ways to run that (line of) code:

  1. Add that code to the setUp()/@Before method of your testcase
  2. In Eclipse, open the Display view, paste the code, select it, right-click and “Inspect” (or CTRL+SHIFT+I)

Once runned, a window will be shown, with a classic db-manager:

hsqldb-manager

Then, do the SQL queries as you need.

Performance of Enum iteration in Java

On Java, the common way to iterate over an Enum is simply:

for (MyEnum d : MyEnum.values()) {
     // do something
}

But you have to know that every time you call to values() method on an Enum, the JVM must to create a copy of the internal array of the Enum values (to prevents users to change its values). This causes a significant performance loss. So, in case that your applications calls recurrently to the Enum.values() method, you can do something like this:

public enum MyEnum {
     A, B, C; // sample values
     public static MyEnum[] values = MyEnum.values();
}

Then, iterate the enum values by using the values variable:

for (MyEnum d : MyEnum.values) {
     // do something
}

Java remote debugging

There are a lot of articles in the web about remote debugging in Java, but it’s necessary to point out one thing. The JVM parameters that you have to set depends on the Java version:

    • before Java 5, use:
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044
    • from Java 5, use:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=1044

For both, the parameters mean:

  • transport: name of the transport to be used when debugging the application (dt_socket for a socket connection)
  • server: “y” if the application listens for a connection at the specified address. “n” if the application attempts to attach to a debugger at the specified address
  • suspend: “n” if the application starts immediately. “y” if the application waits until a debugger has attached to it before executing
  • address: specifies a port number used for communication between the debugger and application

Source: http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/conninv.html#Invocation


Enhanced Links