JDK-6264216 : Allow certain cyclic type references in annotation types
  • Type: Enhancement
  • Component: specification
  • Sub-Component: language
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: generic
  • CPU: generic
  • Submitted: 2005-05-02
  • Updated: 2011-10-31
  • Resolved: 2011-10-31
Related Reports
Relates :  
Relates :  
J2SE Version (please include all output from java -version flag):
  java version "1.5.0_01"
  Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_01-b08)
  Java HotSpot(TM) Client VM (build 1.5.0_01-b08, mixed mode, sharing)

Does this problem occur on J2SE 1.4.x or 5.0.x ?  Yes / No (pick one)

Bug Description:
   Overly agressive application of JLS3 rules to cyclic type references in
   annotation by javac.

   might be related to bug 5044125

   The JLS says (section 9.6 top of page 274 of pre-press online version)

    "It is a compile-time error if an annotation type T contains an element 
     of type T, either directly or indirectly."

   javac is interpreting this rule over agressively as though it said

   "It is a compile-time error if an annotation type T contains an element of 
    type T or T[], either directly or indirectly."

   Fact 1: The JLS does not say "T or T[]". 
   Fact 2: T and T[] are different types. 

  Belief: If the intention of the JLS had been to (carte-blanche) exclude T[] 
          as well as T, it would say so.

  acknowledge the problem caused by the example code in bug 5044125.

  However the following code (in "Stps to reproduce") is essentially the 
  only realistic way to create an annotation to represent a parameterized 
  type (or other tree structures), but the 5044125 "fix" now makes this 
  now illegal.

Proposed JLS clarification

"It is a compile-time error if an annotation type T contains an element of type
T, either directly or indirectly. It is a compile time error if an annotation 
type T contains an element of type T[], either directly or indirectly if that
element has no default value or the default value is not an empty array"

That is cyclic annotation types are permitted where the enclosed reference is T[] 
with a default of {}.

This change would make the "dangerous" code example in 5044125 still illegal, 
but allow those situations where no infinite cycles can be created (except with 
an infinite amount of code).

Steps to Reproduce (be specific):

Compiling this

@interface Type {
    Class<?> value();
    Type[] args() default {};


U:\BCC\java\1.5 stuff\bugs\cyclicAnnotations>javac Type.java
Type.java:3: cyclic annotation element type
    Type[] args() default {};
1 error

But unlike the 5044125 example this example cannot cause infinite recursion and 
is an extremely useful idiom for representing trees, and in particular is the 
only realistic way (tho' oh how I wish there was a better one - but thats a 
separate issue) to represent parameterized types as annotation values.

Example using  HashMap<String,Integer> as an annotation value.

@interface GenerateClass {
	Type supertype();


For real examples of annotations that functionally need to be able to take parameterized types as values see 


both @Mix.base() and @Flavor.value() in this package need to be able to take 
generic types and not just raw types. In this case there is a crude workaround, 
but that workaround cannot be used except where the target of the annotation is 
restricted to class and interface declarations.
###@###.### 2005-05-02 17:20:13 GMT

EVALUATION Proposals for new features in the Java programming language are no longer being accepted or maintained in the bug database at http://bugs.sun.com/. This also applies to proposals for new features in the Java Virtual Machine (that is, in the abstract JVM, as opposed to a JVM implementation like HotSpot). All proposals for new features should be made through the "JDK Enhancement - Proposal & Roadmap Process" described at http://openjdk.java.net/jeps/1. Consequently, this specific request to change the Java programming language will not be considered further. The bug database continues to accept and maintain submissions about technical errors in the design and specification of the Java programming language and the Java Virtual Machine.

EVALUATION In defense of the previous Evaluation, it's a special case for empty arrays because an empty array as the default value would make a self-referencing array type legal when it wouldn't be otherwise.

EVALUATION First, I note that this properly an RFE, not a bug. While the requestor feels that the compiler is being overzealous, I do not. The request here is to change the JLS to make a special case for empty arrays. Such a change would facilitate certain (fairly unusual and infrequent, but very interesting) uses of annotations. The designers of the annotation facility chose, in their wisdom, to disallow recursion in the interests of simplicity. This is one of a number of decisions that restrict the use of annotations to the class of cases envisioned by the industry at the time. For example, becuase annotations cannot be placed on arbitrary nodes of the abstract syntax tree, general purpose typecheckers or other static tools are precluded. Changing the specification to allow more powerful uses of annotations is an intriguing idea. I would therefore consider this request in that broad context. If and when the spec changes, it may be wise to consider how to deal with this issue as well. Even then, I doubt if making a special case for empty arrays is teh way to go. A more general approach (allowing recursion and generating recursive values lazily, for example, or defaulting to null) may work better. I'm putting thison idefinite hold until then.

SUGGESTED FIX a clarification to the JLS, and a change to the compiler to comply with this clarification. ###@###.### 2005-05-02 17:20:13 GMT