Annotation Processing issues on modules

Jonathan Gibbons jonathan.gibbons at oracle.com
Fri Dec 6 01:48:27 UTC 2019


Jeremy,

Thanks for all the details you have provided here, and for all the 
investigations
you have done. It certainly sounds like you have done a great job to track
down the issues.

I've created two separate JBS entries for the issues you describe.

JDK-8235457: Crash when reporting a message about an annotation on a module
https://bugs.openjdk.java.net/browse/JDK-8235457

JDK-8235458: Problem caused by imports in a module-info.java file
https://bugs.openjdk.java.net/browse/JDK-8235458

It would help if we could use separate mail threads for the two separate 
issues,
perhaps using the specific JBS issue number in the subject line.

If you can post your patches to this list 
(compiler-dev at openjdk.java.net) we can
get them turned into webrevs for you and start a review for each of them.

-- Jon


On 12/05/2019 05:22 PM, Jonathan Gibbons wrote:
> Forwarding to compiler-dev; dropping jdk-dev.
>
> -- Jon
>
>
> On 12/05/2019 04:01 PM, Jeremy Kuhn wrote:
>> Hi,
>>
>> I've been working lately on an IoC/DI framework for Java 9+ which 
>> relies on
>> annotation processing and code generation. I'm actually defining
>> annotations on modules and I discovered couple of bugs during the
>> processing of these annotations in the Java compiler.
>>
>> The first one is when we want to print a compilation message targeting a
>> module's annotation, it exists on all versions since JDK 9. Let's say we
>> have the following module descriptor:
>>
>>      @SampleAnnotation
>>      module sampleModule {
>>
>>      }
>>
>> and a properly configured annotation processor to process the
>> @SampleAnnotation, if we do:
>>
>> this.processingEnv.getMessager().printMessage(Kind.MANDATORY_WARNING,
>> "Module warning", element, annotationMirror);
>>
>> where element corresponds to the sampleModule and annotationMirror to 
>> the
>> @SampleAnnotation, the compiler crash with a java.lang.AssertionError:
>>
>> An annotation processor threw an uncaught exception.
>> Consult the following stack trace for details.
>> java.lang.AssertionError
>>       at 
>> jdk.compiler/com.sun.tools.javac.util.Assert.error(Assert.java:155)
>>       at
>> jdk.compiler/com.sun.tools.javac.tree.JCTree$Visitor.visitTree(JCTree.java:3235) 
>>
>>       at
>> jdk.compiler/com.sun.tools.javac.tree.JCTree$Visitor.visitModuleDef(JCTree.java:3227) 
>>
>>       at
>> jdk.compiler/com.sun.tools.javac.tree.JCTree$JCModuleDecl.accept(JCTree.java:2780) 
>>
>>       at
>> jdk.compiler/com.sun.tools.javac.model.JavacElements.matchAnnoToTree(JavacElements.java:298) 
>>
>>       at
>> jdk.compiler/com.sun.tools.javac.model.JavacElements.getTreeAndTopLevel(JavacElements.java:743) 
>>
>>       at
>> jdk.compiler/com.sun.tools.javac.processing.JavacMessager.printMessage(JavacMessager.java:108) 
>>
>>       at
>> jdk.compiler/com.sun.tools.javac.processing.JavacMessager.printMessage(JavacMessager.java:87) 
>>
>>       at
>> processor/com.example.processor.ModuleWarnProcessor.lambda$process$1(ModuleWarnProcessor.java:21) 
>>
>>       at
>> java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) 
>>
>>       at 
>> java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
>>       at
>> java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801) 
>>
>>       at
>> java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658) 
>>
>>       at
>> java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:274) 
>>
>>       at 
>> java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
>>       at
>> java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801) 
>>
>>       at
>> java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) 
>>
>>       at
>> java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) 
>>
>>       at
>> java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) 
>>
>>       at
>> java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) 
>>
>>       at
>> java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) 
>>
>>       at
>> java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497) 
>>
>>       at
>> processor/com.example.processor.ModuleWarnProcessor.process(ModuleWarnProcessor.java:19) 
>>
>>       at
>> jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:1023) 
>>
>>       at
>> jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:939) 
>>
>>       at
>> jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1267) 
>>
>>       at
>> jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1381) 
>>
>>       at
>> jdk.compiler/com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1263) 
>>
>>       at
>> jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:935) 
>>
>>       at 
>> jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:318)
>>       at 
>> jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:176)
>>       at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:57)
>>       at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:43)
>>
>> I've been able to track down the issue in
>> com.sun.tools.javac.model.JavacElements#matchAnnoToTree(), the Vis class
>> does not implement the visitModuleDef() method and as a result it is not
>> possible to find module's annotations hence the AssertionError.
>>
>> The second issue occurs when you want to use imports in a 
>> module-info.java
>> file, if you do so the file is simply ignored during annotation 
>> processing.
>> This issue also exists on all versions since JDK 9. Let's say we have 
>> the
>> following module descriptor:
>>
>>      import com.example.SampleAnnotation;
>>
>>      @SampleAnnotation
>>      module sampleModule {
>>
>>      }
>>
>> and a properly configured annotation processor to process the
>> @com.example.SampleAnnotation, the compiler simply doesn't take the 
>> module
>> into account when processing annotation.
>>
>> I've been able to track down the issue in
>> com.sun.tools.javac.processing.JavacProcessingEnvironment#getModuleInfoFiles() 
>>
>>
>>      private List<ModuleSymbol> getModuleInfoFiles(List<? extends
>> JCCompilationUnit> units) {
>>          List<ModuleSymbol> modules = List.nil();
>>          for (JCCompilationUnit unit : units) {
>>              if (isModuleInfo(unit.sourcefile, 
>> JavaFileObject.Kind.SOURCE) &&
>>                  unit.defs.nonEmpty() &&
>>                  unit.defs.head.hasTag(Tag.MODULEDEF)) {
>>                  modules = modules.prepend(unit.modle);
>>              }
>>          }
>>          return modules.reverse();
>>      }
>>
>> Here it is assumed that the first unit in a module descriptor has to 
>> be a
>> module statement however according to the java language specification, a
>> module descriptor can have import statements before (and this actually
>> compiles just fine) as a result the module is not added to the list of
>> modules candidates for annotation processing.
>>
>> I've also found another more tricky one which relates to the usage of
>> deprecated module in the module providing the annotation processor: 
>> if we
>> create a module which depends on a jdk deprecated module and which 
>> provides
>> an annotation processor, having that module on the processor module path
>> will make the compiler to return with nothing compiled, no error and no
>> output. I didn't dig too much into this as this only impacts jdk9 which
>> comes with deprecated modules (eg. java.se.ee), later versions don't 
>> have
>> any issues for now. I've stopped my investigation in the
>> java.lang.module.Resolver class line 181, deprecated modules are 
>> actually
>> not resolved.
>>
>> I have prepared patches with jtreg tests for the first two issues on the
>> repository head and I'd be happy to submit them. Please let me know 
>> if the
>> description of the issues is clear enough and how we can proceed to fix
>> them, I've already signed the OCA.
>>
>> Jeremy
>



More information about the compiler-dev mailing list