Bug 516212 - Eclipse returns wrong declared methods for an interface
Summary: Eclipse returns wrong declared methods for an interface
Status: NEW
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.6   Edit
Hardware: PC Windows 10
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
Depends on:
Blocks:
 
Reported: 2017-05-04 21:46 EDT by Felipe Pontes CLA
Modified: 2022-07-08 17:47 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Felipe Pontes CLA 2017-05-04 21:46:32 EDT
According to Reflection API documentation (https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getDeclaredMethods--) method Class.getDeclaredMethods() "returns an array containing Method objects reflecting all the declared methods of the class or interface represented by this Class object, including public, protected, default (package) access, and private methods, but excluding inherited methods". When using eclipse to compile and execute program below the returned array has two methods but it should has only one method.

Program

   import java.lang.reflect.Method;

   public interface A {
      public A clone();

      public static void main(String[] args) {
         Method[] methods = A.class.getDeclaredMethods();
         for (Method method : methods) {
            System.out.println(method.toString());
         }
      }	
   }

Current result

   public abstract A A.clone()
   public default java.lang.Object A.clone() throws java.lang.CloneNotSupportedException

Expected result

   public abstract A A.clone()

Configuration

   Software

      O.S.: Windows 10
      Eclipse: Eclipse Neon 4.6

   Hardware: Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz
Comment 1 Stephan Herrmann CLA 2017-05-05 08:17:08 EDT
Of course Eclipse doesn't implement Class.getDeclaredMethods() so we couldn't be blamed if that method were wrong :)

What you are indirectly observing is: different compilers produce or don't produce an additional synthetic bridge method.

javac generates:

  public abstract A clone();
    descriptor: ()LA;
    flags: ACC_PUBLIC, ACC_ABSTRACT

ecj additionally generates:

  public java.lang.Object clone() throws java.lang.CloneNotSupportedException;
    descriptor: ()Ljava/lang/Object;
    flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
    Exceptions:
      throws java.lang.CloneNotSupportedException
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokeinterface #44,  1           // InterfaceMethod clone:()LA;
         6: areturn
      LineNumberTable:
        line 1: 0


This looks funny, indeed, but should be harmless, because for every implementing class the class's version of clone() will override the shown bridge method.

Still needs to be checked against JLS, perhaps we missed a special rule for clone() methods (which are special in several regards).


For applications using Class.getDeclaredMethods() it is always a good idea, to filter out all methods where isSynthetic() answers true.
Comment 2 Felipe Pontes CLA 2017-05-11 21:30:04 EDT
I'm worried about using Method.isSynthetic to check if a method is synthetic (please, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=516540). What do you suggest in this case?
Comment 3 Manoj N Palat CLA 2018-05-16 01:30:29 EDT
Bulk move out of 4.8
Comment 4 Eclipse Genie CLA 2022-07-08 17:47:25 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.