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

Simplifying kSOAP2 clients – Part 2

In the previous post we saw how to simplify a kSOAP2 client by using a template based on the ksoap2-android library. In this time we will get in deep on how to deal with complex types as call parameters or return values, such as lists, arrays and complex objects (complex meaning non-primitive Java types). Again, we will use the kSOAP2 template to simplify the service client code.

In order to simplify the explanation, below are some examples showing how to treat each case. At the end, there is a link to the source code repository to download all of this.

Case 1: Single complex object as parameter

Suppose a service with the following interface:

@WebService(targetNamespace = "http://com.wordpress.jbaris/")
public interface CarService {
	void addCar(@WebParam(name = "car") Car car);
}

where the Car class is:

public class Car {
	private Long id;
	private String name;
	private Manufacturer manufacturer;
	private List<Owner> owners;
	// getters y setters
}
public class Manufacturer {
	private Long id;
	private String name;
	private String country;
	// getters y setters
}
public class Owner {
	private Long id;
	private String name
	// getters y setters
}

The SOAP request must to look like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:com="http://com.wordpress.jbaris/">
   <soapenv:Header/>
   <soapenv:Body>
      <com:addCar>
         <car>
            <id>?</id>
            <manufacturer>
               <country>?</country>
               <id>?</id>
               <name>?</name>
            </manufacturer>
            <name>?</name>
            <!--One or more repetitions:-->
            <owners>
               <id>?</id>
               <name>?</name>
            </owners>
         </car>
      </com:addCar>
   </soapenv:Body>
</soapenv:Envelope>

So, the client code looks like this:

KSoap2Template template;
template.call("addCar", "http://impl.services.com.wordpress.jbaris/addCar",
	new RequestPropertiesSetter() {
		@Override
		public void setValues(SoapObject request) {
			SoapObject owner = new SoapObject(null, "owners");
			owner.addProperty("id", 1L);
			owner.addProperty("name", "John");

			SoapObject owner2 = new SoapObject(null,"owners");
			owner2.addProperty("id", 2L);
			owner2.addProperty("name", "Mary");

			SoapObject manufacturer = new SoapObject(null, "manufacturer");
			manufacturer.addProperty("id", 1L);
			manufacturer.addProperty("name", "Chevrolet");
			manufacturer.addProperty("country", "USA");

			SoapObject car = new SoapObject(null, "car");
			car.addProperty("id", 1L);
			car.addProperty("name", "Aveo");
			car.addProperty("manufacturer", manufacturer);
			car.addSoapObject(owner);
			car.addSoapObject(owner2);

			request.addProperty("car", car);
	}});

Notice that the call method is invoked without a ResponseMapper parameter because it has a void return value. Moreover, the RequestPropertiesSetter parameter adds a property to the target request, property whose name (car) matchs with the web service operation name in the target WSDL. One more important thing: the involved SoapObjects must have a null namespace (the 1st. constructor parameter) and their names (the 2nd. constructor parameter) must match with the target WSDL’s complexTypes.

Case 2: Complex object list as parameter

Suppose a service with the following interface:

@WebService(targetNamespace = "http://com.wordpress.jbaris/")
public interface CarService {
	void addCarList(@WebParam(name = "cars") List<Car> cars);
}

The SOAP request must to look like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:com="http://com.wordpress.jbaris/">
   <soapenv:Header/>
   <soapenv:Body>
      <com:addCarList>
         <!--One or more repetitions:-->
         <cars>
            <id>?</id>
            <manufacturer>
               <country>?</country>
               <id>?</id>
               <name>?</name>
            </manufacturer>
            <name>?</name>
            <!--One or more repetitions:-->
            <owners>
               <id>?</id>
               <name>?</name>
            </owners>
         </cars>
      </com:addCarList>
   </soapenv:Body>
</soapenv:Envelope>

So, the client code looks like this:

KSoap2Template template;
template.call("addCarList", "http://impl.services.com.wordpress.jbaris/addCarList",
	new RequestPropertiesSetter() {
		@Override
		public void setValues(SoapObject request) {
			SoapObject owner = new SoapObject(null,"owners");
			owner.addProperty("id", 1L);
			owner.addProperty("name", "John");

			SoapObject manufacturer = new SoapObject(null, "manufacturer");
			manufacturer.addProperty("id", 1L);
			manufacturer.addProperty("name", "Chevrolet");
			manufacturer.addProperty("country", "USA");

			SoapObject car = new SoapObject(null, "cars");
			car.addProperty("id", 2L);
			car.addProperty("name", "Astra");
			car.addProperty("manufacturer", manufacturer);
			car.addSoapObject(owner);

			SoapObject owner2 = new SoapObject(null, "owners");
			owner2.addProperty("id", 2L);
			owner2.addProperty("name", "Mary");

			SoapObject car2 = new SoapObject(null, "cars");
			car2.addProperty("id", 3L);
			car2.addProperty("name", "Vectra");
			car2.addProperty("manufacturer", manufacturer);
			car2.addSoapObject(owner2);

			request.addSoapObject(car);
			request.addSoapObject(car2);
		}});

Again, the call hasn’t a ResponseMapper parameter because the void return value. The RequestPropertiesSetter adds two “children” objects, just as you add items to a list. The rest is similar to the previous case.

Case 3: Primitive array as parameter

Suppose a service with the following interface:

@WebService(targetNamespace = "http://com.wordpress.jbaris/")
public interface CarService {
	List<Car> getCarsByNames(@WebParam(name = "names") String[] ids);
}

The SOAP request must to look like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:com="http://com.wordpress.jbaris/">
   <soapenv:Header/>
   <soapenv:Body>
      <com:getCarsByNames>
         <!--Zero or more repetitions:-->
         <names>?</names>
      </com:getCarsByNames>
   </soapenv:Body>
</soapenv:Envelope>

So, the client code looks like this:

KSoap2Template template;
List<Car> cars = template.call("getCarsByNames", "http://impl.services.com.wordpress.jbaris/getCarsByNames",
	new RequestPropertiesSetter() {
		@Override
		public void setValues(SoapObject request) {
			request.addProperty("names", "Vectra");
			request.addProperty("names", "Astra");
		}
	}, carListResponseMapper);

In this case, the RequestPropertiesSetter is almost trivial, because the involved parameters are primitives items of an array. The special feature is the multiple invocations to the addProperty method, one per item. However, the key of this call is on the ResponseMapper (called carListResponseMapper). A mapper have to convert the web service response into a Java object, in this case a list of Cars. We’ll dig deeper into mappers in the next case.

Case 4: Primitive list as return value

Suppose a service with the following interface:

@WebService(targetNamespace = "http://com.wordpress.jbaris/")
public interface CarService {
	List<String> getCarNamesList();
}

The SOAP request must to look like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:com="http://com.wordpress.jbaris/">
   <soapenv:Header/>
   <soapenv:Body>
      <com:getCarNamesList/>
   </soapenv:Body>
</soapenv:Envelope>

So, the client code looks like this:

List<String> carNames = getTemplate().call("getCarNamesList", "http://impl.services.com.wordpress.jbaris/getCarNamesList",
	new AbstractResponseMapper<List<String>>() {
		@Override
		public List<String> mapResponse(Object response) {
			return getList(response);
		}
	});

This time, there is no RequestPropertiesSetter because getCarNamesList don’t take parameters. However, the call uses a ResponseMapper to convert the service response into list of String. AbstractResponseMapper is an abstract class that aims to simplifying the mapper implementations by providing the most common conversion methods, e.g. the getList method invoked above.

Case 5: Complex object array as return value

Suppose a service with the following interface:

@WebService(targetNamespace = "http://com.wordpress.jbaris/")
public interface CarService {
	Car[] getCarsArray();
}

The SOAP request must to look like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:com="http://com.wordpress.jbaris/">
   <soapenv:Header/>
   <soapenv:Body>
      <com:getCarsArray/>
   </soapenv:Body>
</soapenv:Envelope>

So, the client code looks like this:

KSoap2Template template;
Car[] cars = template.call("getCarsArray",
				"http://impl.services.com.wordpress.jbaris/getCarsArray",
				carArrayResponseMapper);

Again, this call don’t uses a RequestPropertiesSetter because getCarsArray don’t take parameters. All the magic is on the ResponseMapper (called carArrayResponseMapper):

ResponseMapper<Car[]> carArrayResponseMapper = new AbstractResponseMapper<Car[]>() {
	@Override
	public Car[] mapResponse(Object response) {
		return getArray((Collection<Object>) response, 
				carResponseMapper, Car.class);
	}
};
ResponseMapper<Car> carResponseMapper = new AbstractResponseMapper<Car>() {
	@Override
	public Car mapResponse(Object response) {
		Car result = new Car();
		result.setId(getProperty((SoapObject) response, 
				"id", Long.class));
		result.setManufacturer(getProperty((SoapObject) response,
			"manufacturer", manufacturerResponseMapper));
		result.setName(getProperty((SoapObject) response, "name"));
		result.setOwners(getList((SoapObject) response, 
			"owners", ownerResponseMapper));
		return result;
	}
};
ResponseMapper<Manufacturer> manufacturerResponseMapper = new AbstractResponseMapper<Manufacturer>() {
	@Override
	public Manufacturer mapResponse(Object response) {
		Manufacturer result = new Manufacturer();
		result.setCountry(getProperty((SoapObject) response, "country"));
		result.setId(getProperty((SoapObject) response, 
				"id", Long.class));
		result.setName(getProperty((SoapObject) response, "name"));
		return result;
	}
};
ResponseMapper<Owner> ownerResponseMapper = new AbstractResponseMapper<Owner>() {
	@Override
	public Owner mapResponse(Object response) {
		Owner result = new Owner();
		result.setId(getProperty((SoapObject) response, 
				"id", Long.class));
		result.setName(getProperty((SoapObject) response, "name"));
		return result;
	}
};

Notice that a ResponseMapper can use another ResponseMapper to meet its purpose (e.g. carArrayResponseMapper uses carResponseMapper). Once again, all the mappers extend to AbstractResponseMapper to inherits the common conversion methods.

For a complete set of call alternatives, there is a GitHub hosted project with a JUnit test case (called KSoap2TemplateTest). Feel free to download it and make pull requests to improve it. Again, this code may be incomplete or can be improved, so comments are welcome.

Simplifying kSOAP2 clients

kSOAP2 is a SOAP web service client library for constrained Java environments such as J2ME apps. Ksoap2-android is a fork of kSOAP2 for the Android platform. A typical ksoap2-android client code looks like this.

Inspired by the Spring JDBC template classes, there is below a template for simplifying your kSOAP2 clients:

KSoap2Template.java:

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

public class KSoap2Template {

	private static final ResponseMapper<Object> NULL_RESPONSE_MAPPER = new ResponseMapper<Object>() {
		public Object mapResponse(Object response) {
			return response;
		}
	};

	private static final RequestPropertiesSetter NULL_REQUEST_PROPERTIES_SETTER = new RequestPropertiesSetter() {
		public void setValues(SoapObject request) {
			// do nothing
		}
	};

	private String namespace;
	private String url;

	private String getUrl() {
		return url;
	}

	private String getNamespace() {
		return namespace;
	}

	public KSoap2Template(String url, String namespace) {
		this.url = url;
		this.namespace = namespace;
	}

	public void call(String methodName, String soapAction)
			throws ServiceAccessException {
		call(methodName, soapAction, NULL_REQUEST_PROPERTIES_SETTER);
	}

	public void call(String methodName, String soapAction,
			RequestPropertiesSetter requestPropertiesSetter)
			throws ServiceAccessException {
		call(methodName, soapAction, requestPropertiesSetter,
				NULL_RESPONSE_MAPPER);
	}

	public <T> T call(String methodName, String soapAction,
			ResponseMapper<T> responseMapper) throws ServiceAccessException {
		return call(methodName, soapAction, NULL_REQUEST_PROPERTIES_SETTER,
				responseMapper);
	}

	public <T> T call(String methodName, String soapAction,
			RequestPropertiesSetter requestPropertiesSetter,
			ResponseMapper<T> responseMapper) throws ServiceAccessException {
		try {
			SoapObject request = new SoapObject(getNamespace(), methodName);
			SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
					SoapEnvelope.VER11);
			envelope.setOutputSoapObject(request);
			HttpTransportSE transport = new HttpTransportSE(getUrl());
			requestPropertiesSetter.setValues(request);
			transport.call(soapAction, envelope);
			return responseMapper.mapResponse(envelope.getResponse());
		} catch (Exception e) {
			throw new ServiceAccessException(e);
		}
	}

}

ServiceAccessException.java:

public class ServiceAccessException extends RuntimeException {

	private static final long serialVersionUID = 1L;

	public ServiceAccessException(Throwable throwable) {
		super(throwable);
	}

}

RequestPropertiesSetter.java:

import org.ksoap2.serialization.SoapObject;

public interface RequestPropertiesSetter {

	void setValues(SoapObject request);

}

ResponseMapper.java:

public interface ResponseMapper<T> {

	T mapResponse(Object response);

}

AbstractResponseMapper.java:

package jbaris.wordpress.com.client.ksoap;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;

public abstract class AbstractResponseMapper<T> implements ResponseMapper<T> {

	protected <U> U[] getArray(Collection<Object> collection,
			ResponseMapper<U> itemMapper, Class<U> resultType) {
		final U[] result = (U[]) Array.newInstance(resultType,
				collection.size());
		final Iterator<Object> iterator = collection.iterator();
		for (int i = 0; i < result.length; i++) {
			result[i] = itemMapper.mapResponse(iterator.next());
		}
		return result;
	}

	protected String[] getArray(Object response) {
		String[] result = new String[0];
		if (response instanceof Collection) {
			final Collection<Object> collection = (Collection<Object>) response;
			result = new String[collection.size()];
			final Iterator<Object> iterator = collection.iterator();
			for (int i = 0; i < result.length; i++) {
				result[i] = iterator.next().toString();
			}
		} else if (response != null) {
			result = new String[1];
			result[0] = response.toString();
		}
		return result;
	}

	protected char[] getCharArray(Object response) {
		char[] result = new char[0];
		if (response instanceof Collection) {
			final Collection<Object> collection = (Collection<Object>) response;
			result = new char[collection.size()];
			final Iterator<Object> iterator = collection.iterator();
			for (int i = 0; i < result.length; i++) {
				final String string = iterator.next().toString();
				result[i] = Character.valueOf((char) Integer.parseInt(string));
			}
		} else if (response != null) {
			result = new char[1];
			result[0] = Character.valueOf((char) Integer.parseInt(response
					.toString()));
		}
		return result;
	}

	protected List<String> getList(Object response) {
		final List<String> result = new ArrayList<String>();
		if (response instanceof Collection) {
			final Collection<Object> collection = (Collection<Object>) response;
			for (final Object item : collection) {
				result.add(item.toString());
			}
		} else if (response != null) {
			result.add(response.toString());
		}
		return result;
	}

	protected <U> List<U> getList(Object response, Class<U> resultType) {
		final List<U> result = new ArrayList<U>();
		if (response instanceof Collection) {
			final Collection<Object> collection = (Collection<Object>) response;
			for (final Object item : collection) {
				result.add(valueOf(resultType, item.toString()));
			}
		} else if (response != null) {
			result.add(valueOf(resultType, response.toString()));
		}
		return result;
	}

	protected <U> List<U> getList(Object response, ResponseMapper<U> itemMapper) {
		final List<U> result = new ArrayList<U>();
		if (response instanceof Collection) {
			final Collection<Object> responseCollection = (Collection<Object>) response;
			for (final Object soapPrimitive : responseCollection) {
				result.add(itemMapper.mapResponse(soapPrimitive));
			}
		} else if (response != null) {
			result.add(itemMapper.mapResponse(response));
		}
		return result;
	}

	protected <U> List<U> getList(SoapObject response, String key,
			ResponseMapper<U> itemMapper) {
		final List<U> result = new ArrayList<U>();
		final int propCount = response.getPropertyCount();
		for (int i = 0; i < propCount; i++) {
			final PropertyInfo propInfo = new PropertyInfo();
			response.getPropertyInfo(i, propInfo);
			if (propInfo.getName().equals(key)) {
				result.add(itemMapper.mapResponse(propInfo.getValue()));
			}
		}
		return result;
	}

	protected String getProperty(SoapObject soapObject, String key) {
		return soapObject.getProperty(key).toString();
	}

	protected <U> U getProperty(SoapObject soapObject, String key,
			Class<U> resultType) {
		return valueOf(resultType, getProperty(soapObject, key));
	}

	protected <U> U getProperty(SoapObject soapObject, String key,
			ResponseMapper<U> propertyMapper) {
		return propertyMapper.mapResponse(soapObject.getProperty(key));
	}

	protected <U> U valueOf(Class<U> resultType, Object object) {
		U result;
		if (object == null) {
			result = null;
		} else {
			result = valueOf(resultType, object.toString());
		}
		return result;
	}

	private <U> U valueOf(Class<U> resultType, String valueAsString) {
		try {
			return (U) resultType.getMethod("valueOf",
					new Class[] { String.class }).invoke(resultType,
					new Object[] { valueAsString });
		} catch (final Exception e) {
			throw new IllegalStateException(e);
		}
	}

}

Here are some examples of using the template. Look how simple it becomes your client code:

public class SampleClient {

	private static final String URL = "http://localhost:8080/ws/SampleService";
	private static final String NAMESPACE = "http://sample.org.ar/";
	private KSoap2Template template = new KSoap2Template(URL, NAMESPACE);

	public void callWithVoidResponse() {
		RequestPropertiesSetter rps = new RequestPropertiesSetter() {
			public void setValues(SoapObject request) {
				request.addProperty("aCar", new Car(200L, "A car name"));
			}
		};
		template.call("addCar", "http://impl.service.sample.org.ar/addCar", rps);
	}

	public void callWithoutParams() {
		template.call("getCarNames", "http://impl.service.sample.org.ar/getCarNames",
			new AbstractResponseMapper<List<String>>() {
				public List<String> mapResponse(Object response) {
					return getList(response);
				}
			});
	}

	public Car callWithParamsAndObjectResult() {
		RequestPropertiesSetter rps = new RequestPropertiesSetter() {
			public void setValues(SoapObject request) {
				request.addProperty("carId", 200L);
			}
		};
		return template.call("getCar", "http://impl.service.sample.org.ar/getCar", rps,
			new AbstractResponseMapper<Car>() {
				public Car mapResponse(Object response) {
					Car result = new Car();
					result.setId(getProperty((SoapObject) response, "id", Long.class));
					result.setName(getProperty((SoapObject) response, "name"));
					return result;
				}
			});
	}
}

Obviously this code may be incomplete and may be improved, so comments are welcome.

Android – WiFi disconnected at lock screen

In Android devices, if you want to keep the WiFi connected all the time, even if the screen gets locked, you have to go at:

Settings / Wireles & Network / Wi-Fi settings

then tap on

Menu key  / Advanced

and finally, change the Wi-Fi sleep policy to “Never when plugged in

Android development with Eclipse: a trick

If you get an exception like

Unable to execute dex: Multiple dex files define…

when you are trying to run (or debug) an Android application, just restart Eclipse.

Online XPath Query tool

There is a simple XPath Query tool online at http://www.bit-101.com/xpath/. With this, you can test your XPath expressions quickly. Here is a screenshot of this tool:


Enhanced Links