Thursday, February 22, 2007

Programming to interfaces

We all know that as a good programming practice we should always program against interfaces and not actual subclasses. That's the reason when libraris are designed, they return an interface to an collection and not the actual implementation class.

Recently the developers in my team were facing a problem regarding ClassCast exceptions using Spring JDBC when they upgraded the commons-collection package. After analysis of the source code, it was revealed that the developer was type-casting the List interface to a solid class, i.e. the LinkedHashMap class.

Spring JDBC decides at runtime what Map implementation should be returned. If the latest version of jakarta-commons is available in the classpath, an implementation of org.apache.commons.collections.map.ListOrderedMap is returned, else java.util.LinkedHashMap is used.

Hence the program would start throwing ClassCastExceptions ...See log below comparing what happens depending on the classpath jars:

-- When the latest version of jakarta-commons is not there in the classpath
16-Feb-2007 14:29:47 DEBUG (CollectionFactory.java:142)
org.springframework.core.CollectionFactory -
Falling back to [java.util.LinkedHashMap] for linked case-insensitive map

-- When the latest version of jakarata commons is present
16-Feb-2007 14:31:36 DEBUG (CollectionFactory.java:138) org.springframework.core.CollectionFactory -
Creating [org.apache.commons.collections.
map.ListOrderedMap/CaseInsensitiveMap]

Moral of the story: Always program to interfaces.