JDK-6815786 : (reflect) Class.getDeclaredMethods() is returning inherited methods
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Affected Version: 6u12
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: solaris_10
  • CPU: sparc
  • Submitted: 2009-03-11
  • Updated: 2024-04-12
  • Resolved: 2021-04-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdResolved
Related Reports
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_12"
Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
Java HotSpot(TM) Client VM (build 11.2-b01, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
SunOS folgers.amer.interwoven.com 5.10 Generic_127127-11 sun4u sparc SUNW,Sun-Blade-1500
Linux iwov-livesite-3 2.6.18-53.el5 #1 SMP Wed Oct 10 16:34:02 EDT 2007 i686 i686 i386 GNU/Linux
Microsoft Windows [Version 5.2.3790]

A DESCRIPTION OF THE PROBLEM :
Assume class A is abstract, class B is concrete and extends A.
Calling B.class.getDeclaredMethods() returns class A's method signatures in addition to class B's.

While http://java.sun.com/javase/6/docs/api/java/lang/Class.html#getDeclaredMethods() clearly states that "This includes public, protected, default (package) access, and private methods, but excludes inherited methods."

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create abstract class A with method foo.
2. Create class B extends A without any method.
3. B.class.getDeclaredMethods() returns method foo().

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
method foo() which is inherited from abstract parent class should not be returned from getDeclaredMethods() call.
ACTUAL -
method foo() which is inherited from abstract parent class is returned from getDeclaredMethods() call.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
//---------------- A.java -----------------
abstract class A {
    public void foo() {}
}

//---------------- B.java -----------------
import java.lang.reflect.*;

public class B extends A {
    public static void main(String[] args) throws Exception {
        Method[] methods = B.class.getDeclaredMethods();
        for( int i = 0 ; i < methods.length ; i++ ){
            System.out.println(methods[i]);
        }
    }
}

//-------------- JDK 1.5 run -------------------
> javac *.java
> java -classpath . B
public static void B.main(java.lang.String[]) throws java.lang.Exception

//-------------- JDK 1.6 run -------------------
> javac *.java
> java -classpath . B
public static void B.main(java.lang.String[]) throws java.lang.Exception
public void B.foo()

//--------------- conclusion -------------------
public void B.foo() is returned in JDK 1.6 which contradict with what the JavaDoc states.
---------- END SOURCE ----------

Release Regression From : 5.0u17
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.

Comments
The foo method in B is not inherited from A; it is a bridge method added by the compiler to B, as shown in the javap output: public void foo(); descriptor: ()V flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #60 // Method A.foo:()V 4: return LineNumberTable: line 3: 0 The bridge methods are added in a case like this where a public class public methods from a non-public superclass to allow for the possibility of reflective access of the subclasses methods (JDK-6342411). More explicit documentation of this situation should be added (JDK-8265174). Closing this issue as not a bug.
13-04-2021

Please consider if the documentation for getDeclaredMethods should mention or describe how it is that these methods are included.
04-01-2019

A detailed explanation was provided on this core-libs thread: http://mail.openjdk.java.net/pipermail/core-libs-dev/2019-January/057662.html
03-01-2019

Suspect bridge method is being added from implementing a public methods from a non-public class.
11-04-2013

EVALUATION Will investigate.
22-07-2010