Jan 15 2007
Backward compatibility is a challenge for everyone from the guy writing the kernel to guy building the application.
Raymond Chen has written a lot of anecdotes on compatibility issues in windows. (See Compatibility Constraints and Handling Compatibility Hacks.) He has also authored a book with the same title as that of his blog: The old new thing, which I am sure will have even more interesting tidbits.
Even application developers have to worry about the API they expose and its backward compatibility. The fine people at viewvc believed the URL scheme used by viewvc is part of their “API” and had a thorough discussion on what changes could be made to the URL scheme before and after the 1.0 release!
Being in the middle tier, we seem to face more than our fair share of compatibility issues. First, the product is based on the specifications which are written in English. Each vendor is free to interpret it the way they want. Eventually this leads to customer queries like: “But this works in [plug the customer's current vendor name here]!” This results in new flags in the product configuration files. Over the years we have brought up such ambiguities in the expert groups and the newer versions of the specs clarify the interpretation.
The other category of issues arise from ensuring compatibility with the innumerable combinations of databases, drivers, operating systems and JVMs. JV talks about an issue we recently faced wherein upgrading the VM from 1.4.2_10 to 1.4.2_11 breaks our product. JDK 1.4 introduced a new feature of disconnected sockets. The new implementation was supposed to be backward compatible. However, the implementation had a bug (2126509 ). In the process of fixing this bug in 1.4.2_11, (I believe) they introduced a new bug which breaks backward compatibility.
Such explicit problems are easier to manage than the unwritten contracts. While debugging I rely heavily on the exceptions raised. For example when you cast an object to a type, if there is a ClassCastException, the message generally has the class name of the object. So, in your code, if you are casting to java.util.List and the exception message is java.util.String, you know you are casting a String to a List. Also if you are casting to foo.bar.Klass and the message name is also foo.bar.Klass, then it is a class loading issue. The object you have loaded is of the same class but loaded from a different classloader. Looking at the exception message I could figure out whether it was a genuinely wrong cast or a ClassLoader issue. Unfortunately in JDK 1.4 ClassCastExceptions do not have a message. For a developer this is an annoyance, but is it worth logging a bug?
Here is a sample output with different jdks:
D:\code\41>java -cp PS30\tp\classes ClassCastTest 1.5.0_06 java.lang.ClassCastException: java.lang.String at ClassCastTest.main(ClassCastTest.java:25) D:\code\41>java -cp PS30\tp\classes ClassCastTest 1.4.2_10 java.lang.ClassCastException at ClassCastTest.main(ClassCastTest.java:25) D:\code\41>java -cp PS30\tp\classes ClassCastTest 1.3.1_16 java.lang.ClassCastException: java.lang.String at ClassCastTest.main(ClassCastTest.java:25)
Would you write unit tests for the output messages?