| Summary: | APT: Can't access annotation field which returns Class | ||
|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | James Kingdon <jkingdon> |
| Component: | APT | Assignee: | Walter Harley <eclipse> |
| Status: | CLOSED INVALID | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | eclipse |
| Version: | 3.4 | ||
| Target Milestone: | 3.4.1 | ||
| Hardware: | PC | ||
| OS: | Windows XP | ||
| Whiteboard: | |||
I agree with this analysis of the bug. (Sorry about that...) This should be fixed for 3.4.1. Now that I look closer I think this is by design. See the documentation for com.sun.mirror.declaration.Declaration.getAnnotation(), which says:
"Attempting to read a Class object by invoking the relevant method on the returned annotation will result in a MirroredTypeException, from which the corresponding TypeMirror may be extracted."
So this exception is simply the way that a Class-typed member value is returned; you need to catch it in your own code. Note that even if your processor code is expecting a non-Class-typed return value, APT doesn't know that; if it sees a Class-typed value in the code (even if it is a syntax error) that's what it will report. For example, in the following code, reading the annotation's member value will cause a MirroredTypeException to be thrown:
@interface Anno { int value(); }
@Anno(String.class) class Foo {};
If there's something I'm missing here, please re-open with more detail.
Sorry for wasting your time - I should have checked the docs. No need to apologize - the "docs" on this stuff are pathetic, and the behavior is counterintuitive. It certainly threw me for a loop when I was writing the code. |
Build ID: I20080516-1333 Steps To Reproduce: 1. Call WebServiceRef.type() from annotation processor 2. Get exception: !ENTRY org.eclipse.jdt.apt.core 4 1 2008-06-24 10:37:04.031 !MESSAGE Processor failure during reconcile !STACK 0 com.sun.mirror.type.MirroredTypeException: Attempt to access Class object for TypeMirror org.example.test.Test at org.eclipse.jdt.apt.core.internal.env.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:83) (full stack in More information) More information: Looks like a bug in the following code block in AnnotationInvocationHandler.invoke: final String qName = retType.getTypeDeclaration().getQualifiedName(); // type of annotation member is java.lang.Class if( retType.isClass() && JAVA_LANG_CLASS.equals(qName) ){ // need to figure out the class that's being accessed final ITypeBinding[] classTypes = _instance.getMemberValueTypeBinding(c_methodName); TypeMirror mirrorType = null; if( classTypes != null && classTypes.length > 0 ){ mirrorType = Factory.createTypeMirror(classTypes[0], _instance.getEnvironment() ); } if( mirrorType == null ) mirrorType = Factory.createErrorClassType(classTypes[0]); throw new MirroredTypeException(mirrorType); } Once execution drops into the if( retType.isClass() && JAVA_LANG_CLASS.equals(qName) ){ block, the only way out is by exception. I'm guessing that the throw statement was supposed to be gated by the same if statement that creates the new value for mirrorType in the line above. The version on apt.core plugin is org.eclipse.jdt.apt.core_3.3.100.v20080513-1235.jar The full exception stack is !ENTRY org.eclipse.jdt.apt.core 4 1 2008-06-24 10:37:04.031 !MESSAGE Processor failure during reconcile !STACK 0 com.sun.mirror.type.MirroredTypeException: Attempt to access Class object for TypeMirror org.example.test.Test at org.eclipse.jdt.apt.core.internal.env.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:83) at $Proxy1.type(Unknown Source) at com.ibm.ws.ast.wsfp.annotations.processor.internal.WebServiceRefAP.process(WebServiceRefAP.java:153) at org.eclipse.jdt.apt.core.internal.APTDispatchRunnable.dispatchToFileBasedProcessor(APTDispatchRunnable.java:628) at org.eclipse.jdt.apt.core.internal.APTDispatchRunnable.access$0(APTDispatchRunnable.java:598) at org.eclipse.jdt.apt.core.internal.APTDispatchRunnable$ReconcileEnvCallback.run(APTDispatchRunnable.java:77) at org.eclipse.jdt.apt.core.internal.env.ReconcileEnv$CallbackRequestor.acceptBinding(ReconcileEnv.java:135) at org.eclipse.jdt.core.dom.CompilationUnitResolver.resolve(CompilationUnitResolver.java:759) at org.eclipse.jdt.core.dom.CompilationUnitResolver.resolve(CompilationUnitResolver.java:474) at org.eclipse.jdt.core.dom.ASTParser.createASTs(ASTParser.java:736) at org.eclipse.jdt.apt.core.internal.env.BaseProcessorEnv.createASTs(BaseProcessorEnv.java:855) at org.eclipse.jdt.apt.core.internal.env.ReconcileEnv.openPipeline(ReconcileEnv.java:108) at org.eclipse.jdt.apt.core.internal.env.AbstractCompilationEnv.newReconcileEnv(AbstractCompilationEnv.java:97) at org.eclipse.jdt.apt.core.internal.APTDispatchRunnable.reconcile(APTDispatchRunnable.java:211) at org.eclipse.jdt.apt.core.internal.APTDispatchRunnable.runAPTDuringReconcile(APTDispatchRunnable.java:159) at org.eclipse.jdt.apt.core.internal.AptCompilationParticipant.reconcile(AptCompilationParticipant.java:223) at org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation$1.run(ReconcileWorkingCopyOperation.java:257) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37) at org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation.notifyParticipants(ReconcileWorkingCopyOperation.java:244) at org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation.executeOperation(ReconcileWorkingCopyOperation.java:94) at org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:709) at org.eclipse.jdt.internal.core.JavaModelOperation.runOperation(JavaModelOperation.java:770) at org.eclipse.jdt.internal.core.CompilationUnit.reconcile(CompilationUnit.java:1224) at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile(JavaReconcilingStrategy.java:124) at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.access$0(JavaReconcilingStrategy.java:108) at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy$1.run(JavaReconcilingStrategy.java:89) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37) at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile(JavaReconcilingStrategy.java:87) at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile(JavaReconcilingStrategy.java:149) at org.eclipse.jdt.internal.ui.text.CompositeReconcilingStrategy.reconcile(CompositeReconcilingStrategy.java:86) at org.eclipse.jdt.internal.ui.text.JavaCompositeReconcilingStrategy.reconcile(JavaCompositeReconcilingStrategy.java:102) at org.eclipse.jface.text.reconciler.MonoReconciler.process(MonoReconciler.java:77) at org.eclipse.jface.text.reconciler.AbstractReconciler$BackgroundThread.run(AbstractReconciler.java:206)