JDK-8098840 : Method annotation added in abstract super method
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8u45
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2015-05-26
  • Updated: 2015-06-16
  • Resolved: 2015-06-16
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ExampleAnnotation {}

public abstract class AbstractExample<T extends BeanInterface> {
    public abstract void exampleMethod(T bean);
}

public class ImplementationExample extends AbstractExample<BeanImplementation>{
  @Override
  @ExampleAnnotation
  public void exampleMethod(BeanImplementation bean) {          
  }
}
Where BeanImplementation is an implementation of BeanInterface.

If I compile the code using Java 8u45 and I list which methods of the ImplementationExample class have the annotation ExampleAnnotation using the following piece of code:

    Class<ImplementationExample> cls = ImplementationExample.class;
    List<Method> methods = new ArrayList<Method>();
    methods.addAll(Arrays.asList(cls.getDeclaredMethods()));

    for (Method method : methods) {
      System.out.println("method: " + method.getName() + " annotation: " + method.getAnnotation(ExampleAnnotation.class));
    }
Then I get that both these methods:

ImplementationExample.exampleMethod(BeanImplementation)
ImplementationExample.exampleMethod(BeanInterface)
If I use Java 7 or the Java 8 Eclipse Compiler then only the first method is annotated and this should be the correct behavior.

Is this a bug in the java 8 compiler? Or am I doing something wrong?
I would expect the behavior to be the same as in Java 7.

REGRESSION.  Last worked in version 7u75

ADDITIONAL REGRESSION INFORMATION: 
java version "1.7.0_72"
Java(TM) SE Runtime Environment (build 1.7.0_72-b14)
Java HotSpot(TM) 64-Bit Server VM (build 24.72-b04, mixed mode)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
HERE THE CODE NEEDED
//Test Method Annotation
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ExampleAnnotation {}

//Abstract class with method whose input is parameterized like this:
public abstract class AbstractExample<T extends BeanInterface> {
    public abstract void exampleMethod(T bean);
}

//Implementation of the abstract class 
public class ImplementationExample extends AbstractExample<BeanImplementation>{
  @Override
  @ExampleAnnotation
  public void exampleMethod(BeanImplementation bean) {          
  }
}

//Where BeanImplementation is an implementation of the interface BeanInterface.

If I compile the code using Java 8u45 and I list which methods of the ImplementationExample class have the annotation ExampleAnnotation using the following piece of code:

 Class<ImplementationExample> cls = ImplementationExample.class;
    List<Method> methods = new ArrayList<Method>();
    methods.addAll(Arrays.asList(cls.getDeclaredMethods()));

    for (Method method : methods) {
      System.out.println("method: " + method.getName() + " annotation: " + method.getAnnotation(ExampleAnnotation.class));
    }

Then I get that both these methods:

ImplementationExample.exampleMethod(BeanImplementation)
ImplementationExample.exampleMethod(BeanInterface)

If I use Java 7 or the Java 8 Eclipse Compiler then only the first method is annotated. 


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Only the following method should be detected to have the annotation ExampleAnnotation:

ImplementationExample.exampleMethod(BeanImplementation)
ACTUAL -
Both these two methods have been detected to have the annotation ExampleAnnotation:

ImplementationExample.exampleMethod(BeanImplementation)
ImplementationExample.exampleMethod(BeanInterface)

ERROR MESSAGES/STACK TRACES THAT OCCUR :
No error message 

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
//ExampleAnnotation.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ExampleAnnotation {}

//BeanInterface.java
public interface BeanInterface {}

//BeanImplementation.java
public class BeanImplementation implements BeanInterface {}

//AbstractExample.java
public abstract class AbstractExample<T extends BeanInterface> {
  public abstract void exampleMethod(T bean);
}

//ImplementationExample.java
public class ImplementationExample extends AbstractExample<BeanImplementation>{
	@Override
	@ExampleAnnotation
	public void exampleMethod(BeanImplementation bean) {}
}

//TestAnnotation .java
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class TestAnnotation {
	
	public static void main(String[] args) {
		listAllMethods();
	}

	private static void listAllMethods() {
		Class<ImplementationExample> cls = ImplementationExample.class;
		List<Method> methods = new ArrayList<Method>();
        methods.addAll(Arrays.asList(cls.getDeclaredMethods()));
        for (Method method : methods) {
          System.out.println("method: " + method.getName() + " annotation: " + method.getAnnotation(ExampleAnnotation.class));
    	  System.out.println(method);
		}
	}
}


---------- END SOURCE ----------

SUPPORT :
YES