Friday, September 25, 2009

Character-set Encoding Issues

Great site for inspecting characters to troubleshoot character encoding issues.

Thursday, September 24, 2009

DBUnit and Foriegn Key Constraints


DB Unit is great, except for the FK constraint hell you go through until you learn to do..
1. IDataSet dataset = new FlatXmlDataSet(
ClassLoader.getSystemResourceAsStream(
datasetFilename));
2. dataset = new FilteredDataSet(
new DatabaseSequenceFilter(
getConnection()), dataset);
Line 2 there looks at the constraints and the dataset and determines the correct ordering for the SQL statements for your database, so that when they're run in the setup/teardown of your DBUnit tests you don't get FK constraint violations.

There are many blog postings that give all kinds of ways to disable or defer FK checks by the database, but this works better I think, for me since I have the test setup in Java. This came from the comments in a Matt Raible post from 2006.

Thursday, September 10, 2009

You're in Timeout

I recently had an issue with some code I wrote to connect to a service with a "rest like" interface that returns XML data given a simple query over a HTTP GET request.

I used that java.net.URL class to send the query and retrieve the results as follows..

private InputStream executeQuery(String query) {

InputStream rawResults = null;

try {
query = baseUrl + "?query=" + query;
if(LOG.isDebugEnabled()) {
LOG.debug("Full Query : " + query);
}
URL request = new URL(query);
rawResults = request.openStream();
}
catch (IOException e) {
LOG.warn(e.getMessage(), e);
}

return rawResults;
}

If the host on which this service runs is down (or doesn't exist) before URL.openStream() gets invoked, a java.net.UnknownHostException is quickly thrown (within about 4000 milliseconds), the catch block is executed, and the process goes on.

However, if the service goes down after the socket connection is made, but before the data is read back from the service, this method call to URL.openStream will block indefinitely by default.

Eric Burke has written a post defining this problem and a simple solution, which can be found here. The solution is to set the read timeout on the URLConnection so that you can break after so many milliseconds if you are't getting the data back.

For example:

private InputStream executeQuery(String query) {

InputStream rawResults = null;

try {
query = baseUrl + "?query=" + query;
if(LOG.isDebugEnabled()) {
LOG.debug("Full Query : " + query);
}
URL url = new URL(query);
URLConnection conn = url.openConnection();

// Seems set to 4000ms by default already.
conn.setConnectTimeout( 4000 );

// Set to 0 by default, T/O never occurs!
conn.setReadTimeout( 10000 );

rawResults = conn.getInputStream();

} catch (java.net.UnknownHostException e) {
LOG.warn("Could not make connection to
host within the allotted connectTimeout", e);
} catch (java.net.SocketTimeoutException e) {
LOG.warn("Could finish reading data from the
socket within the allotted readTimeout", e);
}

return rawResults;
}

Now as the catch blocks indicate, the host can go down, or the service can be unresponsive before or during the read, and we'll cut out after our chosen timeout.