RFR: JDK-8213103: RoundEnvironment.getElementsAnnotatedWith(Class) crashes with -source 8

Jan Lahoda jan.lahoda at oracle.com
Thu Nov 1 12:34:10 UTC 2018

Hi Joe,

Thanks for the comments. An updated webrev that uses Feature.MODULES 
instead of Elements.getAllModules, and also updates the copyright year 
as noted by Vicente, is here:

(As a side note, Elements.getAllModules() should be OK performance-wise 
for this purpose, it basically reads an existing/pre-filed field.)

For changing the method to throw IAE, while I agree this situation may 
point out an unintended difference between the compile- and run-time 
environments, sometimes the difference may be intentional (runtime 
dependencies need to be transitive, while compile time don't need to be) 
and may be benign, as is in the case where I've noticed this problem. So 
given the method didn't throw the exception in such cases before, I'd 
rather keep the behavior compatible.


On 31.10.2018 18:27, joe darcy wrote:
> Hi Jan,
> On 10/31/2018 3:50 AM, Jan Lahoda wrote:
>> Hi,
>> When RoundEnvironment.getElementsAnnotatedWith(Class) converts the
>> Class to TypeElement, it uses:
>> eltUtils.getTypeElement(eltUtils.getModuleElement(<class-module-name>), <class-name>)
>> But this fails with -source 8, as there are no module (so
>> getModuleElement returns null, and getTypeElement checks the module
>> parameter is non-null). The proposed fix is to avoid this code.
>> Bug: https://bugs.openjdk.java.net/browse/JDK-8213103
>> Webrev: http://cr.openjdk.java.net/~jlahoda/8213103/webrev.00/index.html
>> Any feedback is welcome,
> Thanks for looking at this issue.
> Stepping back a bit, the API functionality being supported is
>      RoundEnvironment.getElementsAnnotatedWith​(Class<? extends
> Annotation> a)
> and related methods which take in annotation types indicated using Class
> objects (a runtime core reflection representation) and convert them
> internally to TypeElement's (a compile-time representation) by
> extracting the name of the annotation type and then doing various look-ups.
> If the compile-time and runtime environments and configured to be
> consistent with each other, then a runtime annotation type should be
> able to get back a corresponding compile-time representation. However,
> it is possible for the environments to not be consistent, leading to
> this bug and the earlier change 8190886: "package-info handling in
> RoundEnvironment.getElementsAnnotatedWith" which this proposed fix amends.
> The proposed "return null" arm in
> @@ -285,13 +285,15 @@
>           // differ from the single module being compiled.
>           String name = annotation.getCanonicalName();
>           TypeElement annotationElement = eltUtils.getTypeElement(name);
>           if (annotationElement != null)
>               return annotationElement;
> -        else {
> +        else if (!eltUtils.getAllModuleElements().isEmpty()) {
>               String moduleName =
> Objects.requireNonNullElse(annotation.getModule().getName(), "");
>               return
> eltUtils.getTypeElement(eltUtils.getModuleElement(moduleName), name);
> +        } else {
> +            return null;
>           }
>       }
>       private Element mirrorAsElement(AnnotationMirror annotationMirror) {
>           return annotationMirror.getAnnotationType().asElement();
> is basically the handling for an inconsistent environment pre-modules.
> The preceding lines are an, in retrospect, incomplete handling of an
> inconsistent state with modules.
> I recommend the check for "if modules are supported" be implemented
> using a Source-based predicate so that any future dead code will get
> removed once modules are in all supported source levels. In that route
> is not chosen, is getAllModuleElements() a good-performing predicate for
> this purpose?  Would something like "if (getModuleElement​("java.base")
> != null )" be better?
> If the annotation type indicated by the Class object *cannot* be turned
> into an compile-time annotation type, arguably that is an erroneous
> situation that should cause an exception. The IllegalArgumentException
> clauses of
> RoundEnvironment.getElementsAnnotatedWith​(Class<? extends Annotation> a)
> RoundEnvironment.getElementsAnnotatedWithAny​(Set<Class<? extends
> Annotation>> annotations)
> could be expanded to cover this situation and, in the implementation,
> return null replaced by throwing an informative exception.
> What do you think?
> Cheers,
> -Joe

More information about the compiler-dev mailing list