JDK-6322301 : unknown annotations are not ignored in Class.getAnnotations
  • Type: Bug
  • Status: Closed
  • Resolution: Fixed
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Priority: P1
  • Affected Version: 5.0
  • OS: generic
  • CPU: generic
  • Submit Date: 2005-09-10
  • Updated Date: 2012-09-28
  • Resolved Date: 2005-11-01
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 Availabitlity Release.

To download the current JDK release, click here.
Other JDK 6
5.0u6 b04Fixed 6Fixed
Related Reports
Relates :  
Relates :  
Relates :  
If I use Class.getAnnotations to discover all the annotations on a class,
and the class includes annotations that are unknown to the runtime (e.g.,
because the class was annotated with vendor-specific annotations for one
app server and is being deployed on another app server), I get an exception
and can't discover any of the annotations on the class.  According to the
JSR-175 spec lead, unknown annotations must be ignored by getAnnotations.

SUGGESTED FIX src/share/classes/sun/reflect/annotation>sccs sccsdiff -r1.7 -r1.8 AnnotationParser.java ------- AnnotationParser.java ------- 69c69 < Annotation a = parseAnnotation(buf, constPool, container); --- > Annotation a = parseAnnotation(buf, constPool, container, false); 133c133 < Annotation a = parseAnnotation(buf, constPool, container); --- > Annotation a = parseAnnotation(buf, constPool, container, false); 165a166,169 > * > * @param exceptionOnMissingAnnotationClass if true, throw > * TypeNotPresentException if a referenced annotation type is not > * available at runtime 169c173,174 < Class container) { --- > Class container, > boolean exceptionOnMissingAnnotationClass) { 171a177 > String sig = "[unknown]"; 174c180 < String sig = constPool.getUTF8At(typeIndex); --- > sig = constPool.getUTF8At(typeIndex); 180a187,190 > if (exceptionOnMissingAnnotationClass) > // note: at this point sig is "[unknown]" or VM-style > // name instead of a binary name > throw new TypeNotPresentException(sig, e); 183a194,199 > catch (TypeNotPresentException e) { > if (exceptionOnMissingAnnotationClass) > throw e; > skipAnnotation(buf, false); > return null; > } 267c283 < result = parseAnnotation(buf, constPool, container); --- > result = parseAnnotation(buf, constPool, container, true); 342a359,361 > catch (TypeNotPresentException e) { > return new TypeNotPresentExceptionProxy(e.typeName(), e.getCause()); > } 675c694 < result[i] = parseAnnotation(buf, constPool, container); --- > result[i] = parseAnnotation(buf, constPool, container, true);

EVALUATION I've reproduced the reported symptoms with a simple test case. The stack trace for my test is Exception in thread "main" java.lang.TypeNotPresentException: Type b.Bar not present at sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:98) at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:107) at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:31) at sun.reflect.annotation.AnnotationParser.parseSig(AnnotationParser.java:351) at sun.reflect.annotation.AnnotationParser.parseAnnotation(AnnotationParser.java:175) at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:69) at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:52) at java.lang.Class.initAnnotationsIfNecessary(Class.java:3005) at java.lang.Class.getAnnotations(Class.java:2987) at Test.main(Test.java:10) Caused by: java.lang.ClassNotFoundException: b.Bar at java.net.URLClassLoader$1.run(URLClassLoader.java:200) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276) at java.lang.ClassLoader.loadClass(ClassLoader.java:251) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:242) at sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:95) The proximal cause for this problem seems to be the method sun.reflect.annotation.AnnotationParser.parseAnnotation catching NoClassDefFoundError instead of TypeNotPresentException; the latter is thrown by the ParseSig. At the bottom of the stack, sun.reflect.generics.factory.CoreReflectionFactory does a Class.forName on the name of the annotation in question, catches any ClassNotFoundException and throws a TypeNotPresentException instead. Adding a catch block at least gets the simple test case to pass; with this change the core reflection and annotation regression tests still pass too. More analysis will be needed to verify this fix is sufficient and correct.