JDK-8044196 : Incorrect applying of repeatable annotations with incompatible target to type parameter
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8,9
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2014-05-28
  • Updated: 2015-06-04
  • Resolved: 2015-04-30
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.
JDK 9
9 b63Fixed
Related Reports
Blocks :  
Description
Code:
import java.lang.reflect.*;
import java.lang.annotation.*;

@Target({ElementType.TYPE_PARAMETER, ElementType.METHOD})
@Repeatable(TC.class)
@interface T { int value(); }

@Target(ElementType.METHOD)
@interface TC { T[] value(); }

public class RepAnno {

    public class C<@T(1) @T(2) N> {}

}

Could be compiled without any errors. Note, that TC (container annotation) has target = METHOD.

JLS declares (9.7.5. Multiple Annotations of the Same Type):
"If a declaration context or type context has multiple annotations of a repeatable annotation type T, then it is as if the context has no explicitly declared annotations of type T and one implicitly declared annotation of the containing annotation type of T."

Let's check it with reflection API and extend the code:

import java.lang.reflect.*;
import java.lang.annotation.*;

@Target({ElementType.TYPE_PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(TC.class)
@interface T { int value(); }

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface TC { T[] value(); }

public class RepAnno {

    public class C1<@T(1) N> {}
    public class C2<@T(1) @T(2) N> {}

    public static void main(String[] args) {

        Class<RepAnno> cl = RepAnno.class;
        Class<?>[] cs = cl.getDeclaredClasses();

        for (Class<?> c : cs) {
            System.out.println("Class: " + c);
            TypeVariable<?>[] tvs = c.getTypeParameters();
            for (TypeVariable<?> tv : tvs) {
                System.out.println("    T: " + tv.isAnnotationPresent(T.class));
                System.out.println("    TC: " + tv.isAnnotationPresent(TC.class));
            }
        }
    }
}

It's output is:

$ java RepAnno
Class: class RepAnno$C2
    T: false
    TC: true
Class: class RepAnno$C1
    T: true
    TC: false

I.e. TC is applied to type parameter of class C2, although TC target (METHOD) should not be applicable to type parameter. Should be an error instead.
Comments
SQE is ok to defer from 8u20.
25-06-2014

need SQE-OK and maybe change fix version to 9-pool?
24-06-2014

Likely to be closed by pending work.
29-05-2014

Downgraded to P3.
29-05-2014