--- old/src/hotspot/share/oops/klassVtable.cpp 2017-12-04 09:20:27.259695060 -0500 +++ new/src/hotspot/share/oops/klassVtable.cpp 2017-12-04 09:20:27.072895171 -0500 @@ -454,8 +454,11 @@ } else { super_method = method_at(i); } - // Check if method name matches - if (super_method->name() == name && super_method->signature() == signature) { + // Check if method name matches. Ignore match if klass is an interface and the + // matching method is a non-public java.lang.Object method. (See JVMS 5.4.3.4) + if (super_method->name() == name && super_method->signature() == signature && + (!_klass->is_interface() || + !SystemDictionary::is_nonpublic_Object_method(super_method))) { // get super_klass for method_holder for the found method InstanceKlass* super_klass = super_method->method_holder(); @@ -800,8 +803,12 @@ for (const Klass* cursuper = super; cursuper != NULL; cursuper = cursuper->super()) { - if (InstanceKlass::cast(cursuper)->find_local_method(name, signature, - Klass::find_overpass, Klass::skip_static, Klass::skip_private) != NULL) { + Method* found_mth = InstanceKlass::cast(cursuper)->find_local_method(name, signature, + Klass::find_overpass, Klass::skip_static, Klass::skip_private); + // Continue looking if found_mth is a non-public method in java.lang.Object + // because such methods are skipped over during interface method resolution + // and may 'mask' an actual miranda method. + if (found_mth != NULL && !SystemDictionary::is_nonpublic_Object_method(found_mth)) { return false; } }