7122142 : (ann) Race condition between isAnnotationPresent and getAnnotations
Alan Bateman
Alan.Bateman at oracle.com
Wed Jul 3 14:51:30 UTC 2013
On 24/06/2013 19:23, Peter Levart wrote:
>
> Hi Alan,
>
> I have prepared the 2nd revision of the patch:
>
> http://cr.openjdk.java.net/~plevart/jdk8-tl/AnnotationType/webrev.02/
>
> There is a little change in AnnotationParser's alternative parsing
> method. This time the parser does not assume anything about
> annotations being parsed (previously it assumed that they had RUNTIME
> retention). The only difference from standard parsing is that only the
> select annotation types are parsed and the rest are quickly skipped.
> Infinite recursion is broken by the special cased evaluation in
> AnnotationType constructor:
>
> 129 // Initialize retention,& inherited fields. Special treatment
> 130 // of the corresponding annotation types breaks infinite recursion.
> 131 if (annotationClass != Retention.class&&
> 132 annotationClass != Inherited.class) {
> 133 JavaLangAccess jla = sun.misc.SharedSecrets.getJavaLangAccess();
> 134 Map<Class<? extends Annotation>, Annotation> metaAnnotations =
> 135 AnnotationParser.parseAnnotations(
> 136 jla.getRawClassAnnotations(annotationClass),
> 137 jla.getConstantPool(annotationClass),
> 138 annotationClass,
> 139 Retention.class, Inherited.class
> 140 );
> 141 Retention ret = (Retention) metaAnnotations.get(Retention.class);
> 142 retention = (ret == null ? RetentionPolicy.CLASS : ret.value());
> 143 inherited = metaAnnotations.containsKey(Inherited.class);
> 144 }
> 145 else {
> 146 retention = RetentionPolicy.RUNTIME;
> 147 inherited = false;
> 148 }
>
> This is enough to break recursion. The RUNTIME and !inherited
> assumptions for @Retention and @Inherited meta-annotations are
> therefore localized in this code only.
>
> I have also added two tests. The one for detecting deadlock situation
> and the other for consistent parsing of mutually recursive annotations
> in presence of separate compilation.
Sorry for the delay getting back to you on this, I've been busy with
other things.
I'm not an expert on the annotation code but the updated approach to
break the recursion looks good good to me (and a clever approach). Joel
has been on vacation but he told me that he plans to look at this too
(I'm happy to sponsor it in the mean-time as I think the approach is
good and we should get this fix in).
There's another usage of AnnotationParser.parseAnnotation in
TypeAnnotationParser that will need to be updated (I only noticed it
when I grabbed your patch to try it).
A minor comment is that the alignment of the parameter declarations when
they go over multiple lines should probably be fixed up to be consistent
with the other usages.
Thanks for adding tests. One comment on AnnotationTypeDeadlockTest is
that the join(500) might not be sufficient on a very busy system (say
when running tests concurrently) or on a low-end embedded system. So I
think it would be good to bump this up x10. An alternative would be to
not set the daemon status and just let the test timeout if there is a
deadlock. The spin-waits can consume cycles when running tests
concurrently but I don't expect it's an issue here.
A typo in the @summary of AnnotationTypeRuntimeAssumptionTest ("si" ->
"is"). I guess I'd go for slightly shorter lines to make future
side-by-side reviews easier.
Otherwise, this looks good to me.
-Alan.
More information about the core-libs-dev
mailing list