Compatibility in Java may be sometimes counterintuitive even for experienced developers. Lets now have a look what is the source of main obstacles.
Standard Java resolves types (of method signatures) during the compilation. As a consequence, exact type matching is required when Java Linker looks-up elements such as methods.
It brings insufficient flexibility when Java libraries (JAR files) evolve. Even a change that would developers widely expect compatible, is incompatible!
It is just because Java differs in source
and binary
compatibility. In other words, Java Compiler and Java Linker do different jobs. See example:
Client can be compiled with both old and new versions of the library as the update is source
compatible. But what happens when a client is compiled with the old version and someone just update to a new version, i.e. he or she replaces the JAR file. The application will fail!
The client cannot be invoked with the new version once it has been compiled with the old one, as the change is not binary
compatible. In particular, Java Linker cannot cast String
to Object
and it throws an error
instead:
java.lang.NoSuchMethodError: org.apache.commons.io.LineIterator.next()Ljava/lang/String;
How can we deal with this? We can educate developers to know the problem. But it is not effective as developers should concentrate on their job. Better, we can provide tools to help with detecting such obstacles.