| Summary: | Annotations: static fields are allowed - different to javac | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Andrey Loskutov <loskutov> | ||||||
| Component: | Core | Assignee: | Srikanth Sankaran <srikanth_sankaran> | ||||||
| Status: | VERIFIED NOT_ECLIPSE | QA Contact: | Srikanth Sankaran <srikanth_sankaran> | ||||||
| Severity: | major | ||||||||
| Priority: | P3 | CC: | amj87.iitr, jarthana | ||||||
| Version: | 3.6 | ||||||||
| Target Milestone: | 3.8 M5 | ||||||||
| Hardware: | PC | ||||||||
| OS: | Linux | ||||||||
| Whiteboard: | |||||||||
| Attachments: |
|
||||||||
Can you please provide a minimal test case without dependencies which would help us reproduce this issue? An annotation with static fields works fine with both ecj and javac, so dont think thats the problem here. Srikanth, please follow up. Thanks! Created attachment 178687 [details]
Project with ant build file and class files generated by javac
I've tried to strip down all unneeded stuff, but it seems that it is important to have annotations and classes using them in different packages.
You can import zip as java project - all settings are local, and also there are already *.class files generated by my Eclipse and by the ant.
Ant build script is also included.
Ant target is bin2 directory.
In Eclipse everything is compilable.
Running ant (using javac) I see those compile errors:
Buildfile: /home/andrei/workspace/Annotations/build.xml
init:
[mkdir] Created dir: /home/andrei/workspace/Annotations/bin2
build:
[echo] Annotations: /home/andrei/workspace/Annotations/build.xml
[javac] Compiling 6 source files to /home/andrei/workspace/Annotations/bin2
[javac] /home/andrei/workspace/Annotations/src/c/ClassName.java:14: annotation a.SlashedClassName is missing <clinit>
[javac] public static String toSignature(@SlashedClassName String className) {
[javac] ^
[javac] /home/andrei/workspace/Annotations/src/c/ClassName.java:25: annotation a.SlashedClassName is missing <clinit>
[javac] public static @SlashedClassName String fromFieldSignature(String signature) {
[javac] ^
[javac] /home/andrei/workspace/Annotations/src/c/ClassName.java:41: annotation a.SlashedClassName is missing <clinit>
[javac] @SlashedClassName(when=When.UNKNOWN) String className) {
[javac] ^
[javac] /home/andrei/workspace/Annotations/src/c/ClassName.java:40: annotation a.SlashedClassName is missing <clinit>
[javac] public static @SlashedClassName String toSlashedClassName(
[javac] ^
[javac] /home/andrei/workspace/Annotations/src/c/ClassName.java:56: annotation a.SlashedClassName is missing <clinit>
[javac] public static @DottedClassName String toDottedClassName(@SlashedClassName(when=When.UNKNOWN) String className) {
[javac] ^
[javac] /home/andrei/workspace/Annotations/src/c/ClassName.java:69: annotation a.SlashedClassName is missing <clinit>
[javac] public static @SlashedClassName String extractClassName(String originalName) {
[javac] ^
[javac] 6 errors
BUILD FAILED
/home/andrei/workspace/Annotations/build.xml:19: Compile failed; see the compiler error output for details.
Created attachment 178688 [details]
Bytecode diff for ejc/javac code
Additionally here is the visual diff between the generated SlashedClassName.class files.
Hello Andrey, I think this is the Sun compiler bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6857918 See also http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6982543 Here is a slightly modified test case from comment#0 that shows the problem: // ------ import java.util.regex.Pattern; public @interface X { final static String simpleName = "(\\p{javaJavaIdentifierStart}(\\p{javaJavaIdentifierPart}|\\$)*)"; final static String slashedClassName = simpleName + "(/" + simpleName +")*"; final static Pattern simplePattern = Pattern.compile(simpleName); final static Pattern pattern = Pattern.compile(slashedClassName); } class Y { private @X int a; } // ---- Please report this to Sun or track the above bugs. Verified for 3.8M5 |
Tested with Eclipse 3.6.0 / sun JDK 1.6.0_20 on Linux x86_64. The annotation below and another class using it compiles without any warning as Eclipse project with ejc but does NOT compile at all with javac. The problem seems to be the definition of static fields inside the annotation, for which ejc creates <cinit> method, but javac doesn't. javac reports: [echo] compiling findbugs [javac] Compiling 1053 source files to /home/andrei/workspace/findbugs/build/classes [javac] /home/andrei/workspace/findbugs/src/java/edu/umd/cs/findbugs/util/ClassName.java:38: annotation edu.umd.cs.findbugs.internalAnnotations.SlashedClassName is missing <clinit> [javac] public static String toSignature(@SlashedClassName String className) { [javac] ^ [javac] /home/andrei/workspace/findbugs/src/java/edu/umd/cs/findbugs/util/ClassName.java:46: annotation edu.umd.cs.findbugs.internalAnnotations.SlashedClassName is missing <clinit> [javac] public static @CheckForNull @SlashedClassName String fromFieldSignature(String signature) { [javac] ^ [javac] /home/andrei/workspace/findbugs/src/java/edu/umd/cs/findbugs/util/ClassName.java:84: annotation edu.umd.cs.findbugs.internalAnnotations.SlashedClassName is missing <clinit> [javac] @SlashedClassName(when=When.UNKNOWN) String className) { [javac] ^ [javac] /home/andrei/workspace/findbugs/src/java/edu/umd/cs/findbugs/util/ClassName.java:83: annotation edu.umd.cs.findbugs.internalAnnotations.SlashedClassName is missing <clinit> [javac] public static @SlashedClassName String toSlashedClassName( [javac] ^ [javac] /home/andrei/workspace/findbugs/src/java/edu/umd/cs/findbugs/util/ClassName.java:99: annotation edu.umd.cs.findbugs.internalAnnotations.SlashedClassName is missing <clinit> [javac] public static @DottedClassName String toDottedClassName(@SlashedClassName(when=When.UNKNOWN) String className) { [javac] ^ [javac] /home/andrei/workspace/findbugs/src/java/edu/umd/cs/findbugs/util/ClassName.java:164: annotation edu.umd.cs.findbugs.internalAnnotations.SlashedClassName is missing <clinit> [javac] public static @SlashedClassName String extractClassName(String originalName) { [javac] Original code: import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import javax.annotation.RegEx; import javax.annotation.meta.TypeQualifier; import javax.annotation.meta.TypeQualifierValidator; import javax.annotation.meta.When; /** * * Denotes a class name or package name where the / character is used to separate package/class name components. * @author pugh */ @Documented @TypeQualifier(applicableTo=CharSequence.class) @Retention(RetentionPolicy.RUNTIME) public @interface SlashedClassName { final static String simpleName = "(\\p{javaJavaIdentifierStart}(\\p{javaJavaIdentifierPart}|\\$)*)"; final static String slashedClassName = simpleName + "(/" + simpleName +")*"; final static Pattern simplePattern = Pattern.compile(simpleName); final static Pattern pattern = Pattern.compile(slashedClassName); When when() default When.ALWAYS; static class Checker implements TypeQualifierValidator<SlashedClassName> { public When forConstantValue(SlashedClassName annotation, Object value) { if (!(value instanceof String)) return When.NEVER; if (pattern.matcher((String) value).matches()) return When.ALWAYS; return When.NEVER; } } }