Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happened to Java Binary Compatibility?

Tags:

java

history

I came across an old set of classes dated March 1997. It was during the time when I tried to learn Java, and it was JDK 1.0.2

Interestingly enough, I have both the source files and the class files intact from that time. The sources still compiles and executes as expected, which was really cool. But wasn't Java supposed to retain binary compatibility as well? Well, somewhere along the way, the format no longer holds valid. A Java 8 VM will report;

Exception in thread "main" java.lang.ClassFormatError: Invalid start_pc 65535 in LocalVariableTable in class file bali/core/Application
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:455)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    :
    [snip many ClassLoader calls]
    :
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)

The offending class is the superclass of the class that I call from command line.

One more detail, in those days, Microsoft was still in the Java camp, and I remember that their javac was more compliant against badly written syntax. The Sun compiler would gladly accept "public synchronized class Abc" and many other invalid statements. So, there is a big chance that these class files were generated by the MS compiler, and was then run on Sun JVM.

Anyway, my question is; Is there anyone around who has knowledge about the compatibility commitment in the early versions of Java? Was it a big deal, or was it sacrificed on purpose? Or was there a decision much later, say Java 1.4 or Java 5 to simply drop JDK 1.0 support??

like image 422
Niclas Hedhman Avatar asked Apr 16 '16 05:04

Niclas Hedhman


1 Answers

As you mentioned the issue was likely introduced when the compiler switched from the Microsoft compiler to the Sun compiler. Sun stated that the class files generated by the Microsoft compiler did not follow the Java specification and thus were not valid.

You can find more details here:

This error is caused by bytecode generated from old JDK 1.0.2 or 1.1 compilers. In the past, a lot of these compilers generated bytecode that does not conform to the Java VM Specification. Since the verifiers in recent J2SE releases are much stricter about bad class format, the ClassFormatError is thrown by the VM when these bad class files are loaded.

Regarding the general question, Java is still firmly committed to backwards compatibility and there has never been a major break. There are usually minor breaks from release to release on fringe issues. I know of no master table but here are tables for individual versions:

  • Java 8 (fully binary compatible with Java 7)
  • Java 7 (mostly binary compatible with Java 6)
  • Java 6 (mostly binary compatible with Java 5, plus a comment that some obfuscators generated class files outside the spec and thus those class files may not run)
  • Java 5 (mostly binary compatible with Java 1.4.2, plus the same comment about obfuscators)
  • Java 1.0 - 1.4.2 (mostly binary compatible with previous versions, some comments that forward compatibility may even work but isn't tested)
like image 69
Pace Avatar answered Oct 12 '22 00:10

Pace