# Friday, 04 November 2011
« Java Method Overriding Is FUBAR Part 4 o... | Main | Java Method Overriding Is FUBAR Part 6 o... »
Java Method Overriding Is FUBAR Part 5 of ∞

One of the bizarre things is that the method overriding behavior changed between Java 6 and Java 7 (and HotSpot preserves the Java 6 behavior for classes that have major class file version < 51), but the spec doesn't mention this at all, where it generally is pretty good about mentioning different behavior based on class file version.

Here's an example that uses a class hierarchy that mixes version 50 and 51 classes to confuse HotSpot JDK 7:

package p1;

public class A
{
  { foo(); }
  public void foo() {
    System.out.println("A.foo");
  }
  public static void main(String[] args) {
    new p4.D();
  }
}

package p2;

public class B extends p1.A
{
  { foo(); }
  void foo() {
    System.out.println("B.foo");
  }
}

package p3;

public class C extends p2.B
{
  { foo(); }
  void foo() {
    System.out.println("C.foo");
  }
}

package p4;

public class D extends p3.C
{
  { foo(); }
  void foo() {
    System.out.println("D.foo");
  }
}

Here's a table view of the structure:

p1   p2   p3   p4
A      
  B    
    C  
      D

After you compile this with javac 7 (again using the trick to first compile without the public modifier on A.foo) then use a hex editor to modify p3/C.class to change the class file version from 51 (33 hex) to 50 (32 hex) at offset 7 in the file.

When you run it you get:

D.foo
D.foo
Exception in thread "main" java.lang.AbstractMethodError: p3.C.foo()V
        at p3.C.(C.java:5)
        at p4.D.(D.java:3)
        at p1.A.main(A.java:10)

(This is a variation of the bug I reported here.)

Friday, 04 November 2011 08:54:44 (W. Europe Standard Time, UTC+01:00)  #    Comments [2]
Thursday, 10 November 2011 16:43:45 (W. Europe Standard Time, UTC+01:00)
I'm not a java programmer (so answering your "lame" captcha is not so easy) but should "use a hex editor to modify p3/C.class to change the class file version from 51 (33 hex) to 50 (32 hex) at offset 7 in the file" really be considered to be a kosher/supported thing to do?
Thursday, 10 November 2011 17:22:02 (W. Europe Standard Time, UTC+01:00)
That's just an easy way to achieve this scenario, but when you combine multiple libraries into your application you often end up with different version class files loaded. So, while very unlikely, this is possible in real life as well.

But that's really missing the point. My point is that HotSpot's method overriding implementation is just too complicated (and a bad spec also doesn't help) and that results in weird bugs like this.
Name
E-mail
Home page

I apologize for the lameness of this, but the comment spam was driving me nuts. In order to be able to post a comment, you need to answer a simple question. Hopefully this question is easy enough not to annoy serious commenters, but hard enough to keep the spammers away.

Anti-Spam Question: What method on java.lang.System returns an object's original hashcode (i.e. the one that would be returned by java.lang.Object.hashCode() if it wasn't overridden)? (case is significant)

Answer:  
Comment (HTML not allowed)  

Live Comment Preview