#159 Incorrect overridden static method resolution in derived cls

open
nobody
General (151)
8
2004-03-12
2004-03-12
Shankar Unni
No

If you have a derived class that overrides a base
class' static method with an identical signature, and
call the derived method with an object that belongs to
a subtype of the argument type, then bsh calls the base
class'
static method. (Does not happen if the actual argument
passed is an exact match for the parameter type.)

This worked fine with 1.3.0.

Here's the most basic test case:

==== test/Base.java ====
package test;

public class Base {
public static void mymethod(MyIF s)
{
System.out.println("Base " + s);
}
}

==== test/Derived.java ====
package test;

public class Derived extends Base {
public static void mymethod(MyIF s)
{
System.out.println("Derived " + s);
}
}

==== test/MyIF.java ====
package test;

interface MyIF {}

==== test/MyIFImpl.java ====
package test;

public class MyIFImpl implements MyIF {
String _s;
public MyIFImpl(String s)
{
_s = s;
}
public String toString()
{
return _s;
}
}

==== test.bsh ====
foo = new test.MyIFImpl("foo");
test.Derived.mymethod(foo); // prints "Base foo"!

===================

Discussion

  • Shankar Unni
    Shankar Unni
    2004-03-12

    • priority: 5 --> 8
     
  • Shankar Unni
    Shankar Unni
    2005-05-17

    Logged In: YES
    user_id=167432

    FYI - still broken in bsh 2.0 b2.

     
  • Logged In: NO

    BeanShell is cool and still quite useful. But I get the
    idea that no one is maintaining it anymore. I just ran
    into this bug with 2.0b4.

     
  • Shankar Unni
    Shankar Unni
    2006-09-09

    Logged In: YES
    user_id=167432

    The problem is that the findMostSpecificSignature() test for
    "most specific" does:

    if (isSignatureAssignable(ideal, current) &&
    (bestMatch == null ||
    isSignatureAssignable(current, bestmatch)) {
    // replace bestMatch with current.
    }

    The problem is that "isSignatureAssignable" returns true if
    you pass in two exactly identical signatures from different
    classes.

    When the "candidates" array is built up, it contains first
    the target class' methods, and then the methods from the
    base classes of the target class.

    So if the target class overrides a method from the base
    class, the second method (from the base class) matches the
    test above, and we end up setting bestMatch to the base
    class method.

    Really, the entire findMostSpecificSignature() method is a
    big botch (sorry!), and needs to be completely rewritten to
    conform to the JLS rules. Currently, it doesn't detect truly
    ambiguous calls, and it will almost certainly need major
    hacking for Java5 extensions.

    But for now, my fix was to make an additional check for
    whether "bestMatch" and "current" were identical, and if so,
    don't replace bestMatch with "current".

    Patch coming up.

     
  • Shankar Unni
    Shankar Unni
    2006-09-09

    minimal patch to fix the described symptoms