-
Enhancement
-
Resolution: Won't Fix
-
P4
-
None
-
5.0
-
generic
-
generic
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)
5.0
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 {};
}
gives
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();
}
@GenerateClass(supertype=@Type(value=HashMap.class,args={@Type(String.class),@Type(Integer.class)}))
For real examples of annotations that functionally need to be able to take parameterized types as values see
https://rapt.dev.java.net/nonav/docs/api/index.html?net/java/dev/rapt/exploratory/mixin/package-summary.html
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
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)
5.0
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 {};
}
gives
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();
}
@GenerateClass(supertype=@Type(value=HashMap.class,args={@Type(String.class),@Type(Integer.class)}))
For real examples of annotations that functionally need to be able to take parameterized types as values see
https://rapt.dev.java.net/nonav/docs/api/index.html?net/java/dev/rapt/exploratory/mixin/package-summary.html
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
- relates to
-
JDK-4906400 (JSR175) compiler allows self-containing annotation types
- Resolved
-
JDK-5044125 javac allows cyclic annotation interfaces with arrays
- Resolved