@Value not resolved when using @PropertySource annotation.

Spring’s gotcha-of-the-day is around using @Value to resolve property placeholders in combination with @PropertySource. I had the following Spring Java configuration: @Configuration @PropertySource("classpath:/test.properties") public class TestAppConfig { @Value("${queue.name}") private String queue; @Bean(name="queue") public String getQueue() { return queue; } } But the value in “queue” was not resolving - it returned “${queue.name}” as the value. It turns out that I needed the following magical incantation to get it to work. [Read More]
Java  Spring 

Scheduled tasks with Spring and Java configs

Spring 3.2 has some very nice features for scheduling tasks. The pure Java way of doing this looks something like private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); class ScheduledTask implements Runnable { @Override public void run() { System.out.println("Running scheduled task"); } } // Schedule a task every 5 seconds executor.scheduleAtFixedRate(new ScheduledTask(), 1, 5, TimeUnit.SECONDS); // If you don't do this then the JVM won't exit cleanly executor.shutdown(); But now, with the snazzy new Spring scheduling annotations, it can be as simple as this [Read More]
Java  Spring 

Converting from JUnit to TestNG

The TestNG Eclipse plugin has a feature that will convert your unit tests from JUnit to TestNG in a few simple clicks, and it works pretty well for the most part. However, I soon noticed that it was replacing Assert.assertX with AssertJUnit.assertX. Upon further inspection, this was because TestNG’s Assert uses different argument ordering. For example // JUnit Assert.assertEquals(message, expected, actual); // TestNG Assert.assertEquals(actual, expected, message); Each argument has moved. [Read More]

Using Factory Beans in Spring Java Configs

I recently went through an exercise of converting Spring XML configuration files to Java-based configuration. The process went well for the most part, but I encountered an oddity around how to use factory beans when using Java configs. In XML, factory beans would be used like this <bean id="MyDataSource" class="org.springframework.jndi.JndiObjectFactoryBean" p:jndiName="jdbc/MyDataSource" p:resourceRef="false" /> In Java however, this has to be separated into two separate @Beans @Bean public JndiObjectFactoryBean getJndiObjectFactoryBean() { JndiObjectFactoryBean jndi = new JndiObjectFactoryBean(); jndi. [Read More]
Java  Spring 

Atomic construction

Bugs caused by multi-threading can be very difficult to find. Here’s one I encountered recently. private static MyObject INSTANCE; public void init() { if( INSTANCE == null) { initInstance(); } } private static synchronized void initInstance() { if( INSTANCE != null) { return; } INSTANCE = new MyObject(); INSTANCE.initThis(); INSTANCE.initThat(); } At first glance, this code is fine. It uses a synchronized static method to create the singleton, using double-checked locking to make sure it only gets created once. [Read More]

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 

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]

Broken Generics

Given the following code Map<String, String> map = new HashMap<String, String>(); map.put("123", "value"); Integer key = Integer.valueOf(123); String actual = map.get(key); What is the value of “actual”? Compilation error - key should be a String “value” null Answer: null This blew me away. The whole point of type-safe collections was supposed to provide compile-time checking. However, the only generics method on the Map class is put(K, V). So calling get(Object) doesn’t cause a compilation error, but merely returns null. [Read More]
Java