Community
Participate
Working Groups
If I have the following class definition: @Deprecated @Invalid public class NotWorking { } where @Deprecated is a valid annotation and @Invalid is an invalid annotation (not resolved), I would expect that the ITypeBinding.getAnnotations() method returns an array with the @Deprecated annotation. But, in fact, the latter method returns an empty array of annotations. If I comment the @Invalid annotation then the ITypeBinding.getAnnotations() method returns correctly an array with the @Deprecated annotation. The above example is only for illustration of the problem and is not the real case where the problem has been caught.
Created attachment 74785 [details] test case test case that illustrates the problem
This is something we need to improve. Right now as soon as one of the annotations cannot be resolved, the returned value is an empty array. We might need to change this in order to improve the apt tooling. Walter, this might be one example of the cases we need to improve for apt. I was thinking of creating a recovered binding in this case.
Returning only one annotation is not really an option as there is no way for the user to find out that one annotation could not be resolved.
The related bug is Bug 196200 (which considers both the case of invalid annotations on valid elements, and valid annotations on invalid elements).
As mentioned in comment #2 if one of the annotations is not resolved, then none of the the list of annotations to this TypeBinding is an empty array. In fact, all other valid annotations are not recognized. I understand that simply returning an array of only the resolved annotation is not the best solution (comment #3), but this is much better than the current situation. Let me give an example in the Java EE context. We build a model of an EJB project. The model parses the Java annotations on the EJB classes. Let's have an interface annotated with the @Remote annotation. The model considers this interface as a Remote business interfaces, which is correct. If the user enters an invalid annotation right after the @Remote one, then the @Remote annotations is no more resolved. Now the model considers this interface as a Local business interface, because the Java EE spec says that if an interface is not annotated, then it is a Local one. Well, this situation effectively breaks our model.
Created attachment 76668 [details] patch This patch fixes the TypeBinding.getAnnotations() method. Before: if one of the annotations is not resolved then the return value is an empty array. Now: the unresolved annotations are ignored and the return value is an array of all resolved annotations. This patch effectively solves certain use cases mentioned in the previous comment. Please, consider this patch for 3.3.1.
Philippe, Jérôme, Kent, do you see any potential problems by adding resilience in the annotation resolution? We already do something similar for fields and methods where we use availableFields() and availableMethods() which prune all unresolvable methods or fields.
Martin, you might want to add a comment here.
To comply with the JSR269 spec we will need to do a bit more than Kaloyan's patch; we actually need to provide at least partial information on the unresolved annotations, i.e., we need to represent them with a token that is the equivalent to what would exist if an empty annotation type of the same name were resolved. So, Kaloyan's patch might be appropriate and good enough for 3.3.1 but probably not enough for 3.4.
Maybe we can use recovered bindings here? It would be better if the binding array size has the same size as the number of annotations.
For 3.3.1, I think the patch is good enough. The spec says that it should return the list of *resolved* annotations. So there is no guaranty that if an annotation cannot be resolved, it should be in the list. So no client should rely on the fact that the number of returned annotation bindings is the same as in the source. However, if we can use recovered bindings for 3.4, that would be better.
+1 for the current patch for 3.3.1
+1 for the current patch for 3.3.1 as a client of IBinding#getAnnotations() has no workaround for this problem.
Created attachment 76845 [details] Proposed fix This patch doesn't create a list when all annotations can successfully be resolved and is closer to what is done in other places in the dom package.
Created attachment 76846 [details] Regression test
Released patch for 3.3.1.
Reopen for 3.4
Released the patch also in HEAD to keep a consistent behavior between HEAD and 3.3 maintenance stream. I keep this bug open to improve the support in HEAD.
Closing as a dup of bug 196200. With support for bug 196200, you know get all annotations even the ones that cannot be resolved. *** This bug has been marked as a duplicate of bug 196200 ***
You can even check that the binding for @Invalid is recovered.
I'm not really sure that this bug should have been set as duplicate of 196200. IMO, it should have been set as FIXED while releasing the patch applied onto R3_3_maintenance stream. Then, either add a test case to bug 196200 or open a new bug to track behavior enhancement in this area (type annotations) after the missing types patch was released... The problem is that the recovered annotation does not work properly. In this case, isRecovered() method returns false although I expected it to be true. And I cannot reopen this bug because it's a duplicate of another one... To make simple, I consider this one as verified for 3.4M6 using build I20080324-1300, but I'll reopen a new one for the problem of the incorrect isRecovered returned value...
Closing