A collection of thoughts, ideas and rants inspired by my career in the fintech and banking industry.

Writing deterministic tests

Non-deterministic unit tests are like kryptonite for an automated build. They cause intermittent build failures and the development team becomes accustomed to ignoring a failing build. This is a Bad Thing.

Thread.sleep(x) in a unit test is a recipe for non-deterministic behaviour. Think about what happens when this test is run on a slow machine. How big does X need to be?

I often see this anti-pattern in multi-threaded code where the test case is waiting for some asynchronous task to complete, and the test case has to guess at how long the task will take, and then asserts on some condition that the task was supposed to change.

[Read More]

List.clear() throws UnsupportedOperationException

Consider the following code

String[] s = new String[]{""};  
List<String> list = Arrays.asList(s);  
list.clear();  

All looks good, right? When you run it you get:

java.lang.UnsupportedOperationException  
	at java.util.AbstractList.remove(AbstractList.java:144)  
	at java.util.AbstractList$Itr.remove(AbstractList.java:360)  
	at java.util.AbstractList.removeRange(AbstractList.java:559)  
	at java.util.AbstractList.clear(AbstractList.java:217)  

This is because Arrays.asList(array) returns a fixed-size list backed by the specified array. Fixed-size being the operative word.

Java 

Arrays.asList() gives a list with wrong size

Try this out for fun.

int[] i = new int[]{1, 2, 3};  
System.out.println(Arrays.asList(i).size());

Integer[] ii = new Integer[]{1, 2, 3};  
System.out.println(Arrays.asList(ii).size());  

Output:
1
3

What the hell, Java? This is totally unexpected behaviour!

In this case Java is being a bit pedantic. See, Collections can contain only contain Objects, and an int is not an Object but int[] is an Object, so that’s why you get a list with only 1 element.

[Read More]
Java 

How to set JMSXUserID in Websphere MQ using Spring JMS

Every time I work with MQ and Spring JMS I want to poke my eyes out with a dull instrument. It’s always a pain in the neck. My most recent challenge was trying to get the JMSXUserID field to flow through to the application on the other side of MQ.

First, I created a MessagePostProcessor to add the JMS header

public class MyMessagePostProcessor implements MessagePostProcessor  
{  
	private String userId;

	@Override  
	public Message postProcessMessage(Message msg) throws JMSException  
	{  
		msg.setStringProperty(JmsConstants.JMS_IBM_MQMD_USERIDENTIFIER, userId);  
		msg.setStringProperty("JMSXUserID", userId);  
		return msg;  
	}  
}  

But when I checked the queue with HermesJMS I could see that the JMSXUserID had been overwritten somewhere, so I fired up WireShark and watched for the message and confirmed that the message that was going over the wire already had the JMSXUserID field overwritten. This was a good thing - the issue was in the IBM MQ JMS client code.

[Read More]

Big Data and HR

This piece from the New York Times touches on a subject that I’m passionate about - the challenges of hiring good people. Deep into it, it mentions that:

“…the most proven method, Dr. Lewin said, is a referral from someone already working there. Current employees know the culture, he said, and have their reputations and their work environment on the line.”

The big data thing is a cool, tech solution, but really it’s referrals that matter.

[Read More]

Can not execute Sonar: Missing column: period in ALERTS

I recently encountered the following error in Sonar 3.5

[ERROR] Failed to execute goal org.codehaus.mojo:sonar-maven-plugin:2.0:sonar
(default-cli) on project smartfx: Can not execute Sonar: Missing column:period in DB.ALERTS -> [Help 1]  
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal
org.codehaus.mojo:sonar-maven-plugin:2.0:sonar (default-cli) on project	myproject: 
Can not execute Sonar  
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:	203)  
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:	148)  
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:	140)  
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)  

A quick check of the database revealed that the ALERTS table does indeed contain a column named ‘period’.

[Read More]
Sonar 

hg clone fails with 255 error

I recently encountered an issue with cloning a Mercurial repository where it would fail with an obtuse error stating that “[command returned code 255 Mon Mar 25 11:39:55 2013]”. My initial Googling implied that this was caused by a server timeout but the problem persisted even after increasing the timeout on our Apache web server.

The clone was always failing on one particular file - a 600Mb binary. (Don’t ask…)

[Read More]

The Guild

Troy Hunt’s Ghost Who Codes ignited something inside me. Initially I was a little insulted because I don’t have much of an online presence apart from my blog and my Twitter account. There are many reasons for this but in the end it doesn’t matter.

You see, as much as I respect Troy, I think he’s missing the point.

The best developers rarely apply for advertised jobs. They’re hired through their network and are never on the market. They’re members of The Guild; they’re the fat guys who know C++.

[Read More]

Apache commons for readability

There are many short methods in the Apache Commons libraries that seem like overkill at first glance, however, their purpose becomes more apparent when you examine the effect that these methods have on the readability of the caller.

I see a lot of code that does stuff like this:

if( s == null || "".equals(s.trim())) {  
	// Do something  
}  

which could be re-written as

if( StringUtils.isBlank(s)) {  
	// Do something  
}  

Personally, I find it much easier to understand the intent of the second version.

[Read More]

SonarException: The project is already been analysing.

I was getting this error when running a Sonar analysis recently.

This was caused by the Jenkins/Sonar process getting killed while the project analysis is underway. Sonar now uses a database semaphore to prevent multiple builds running at the same time, but if the job gets terminated then the semaphores don’t get cleaned up.

To fix the problem: Log into the database and delete any rows in the ‘semaphores’ table.

[Read More]
Sonar