Java programmers be warned. Those ".class" files are not as flexible as you think.
When grading the programs for the compilers class, I ran across an interesting problem. The student's program was throwing an "IncompatibleClassChangeError". I thought it unacceptable for the program to throw an uncaught exception, so I deducted some points. Shortly after I emailed out the grade report, the student emailed me saying the program was not throwing any exceptions on his machine. After emailing back and forth, we ended up sitting down at the same computer to figure out what was going on.
The students in CS 480 were given a suite of ".java" files that provide a basis for their program. They were to only modify "SymbolTable.java" and "Parser.java" to complete the functionality. The exception was being thrown in "ClassType.java", a file the student had not modified. Even more perplexing, the "ClassType.class" file generated in the student's home directory was different than the "ClassType.class" file generated in Dr. Budd's directory--even though the "ClassType.java" files were identical!
After much frustration and "diff"ing, we finally figured out the student had changed "SymbolTable" from an interface to a class. "ClassType" contained a reference to "SymbolTable" as one of its data members. The byte code generated for a reference to an interface is different than a reference to a class, even though they are linguistically interchangeable. Although you can change an interface to a class and all your code will compile just fine, the byte code generated will be different. This means that if you write a library and you promote an interface to a class, you cannot use the old ".class" files to compile against library. Even worse, compiling against the old ".class" files will succeed, but running the program will cause run-time exceptions. Why doesn't the compiler check for this?
I find problem very interesting because in Java, a variable of an interface type is a replacement for a variable of the class type and visa-versa. (Yes, yes, so long as you are only calling methods that exists in both the interface and the class.) Essentially, the two are substitutes for each other. That might lead one to believe that it will be the same in the byte code. Well, it's not. Be warned!
Posted by enigma at March 8, 2004 10:20 PM