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.
|