[
https://issues.apache.org/jira/browse/MCOMPILER-424?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17797351#comment-17797351
]
Alexander Kriegisch edited comment on MCOMPILER-424 at 12/16/23 3:30 AM:
-------------------------------------------------------------------------
FWIW, I cloned the sample project and found out that
* the issue still occurs in Maven Compiler 3.11.0,
* it also occurs on JDKs 17 and 21 and there no combination of source, target
or release (1.8, 11, 17, 21) seems to make it go away,
* the fact that it works on JDK 11 with release 11 seems to be a fluke.
The most important finding, however, is that this issue is *not
MCOMPILER-related at all.* With the same JDK versions and the same compilation
options on the console using _javac_, the very same symptoms reproduce. Again,
I tried 8, 11, 17, 21. I am suggesting to close this issue. If you think that
this is a _javac_ or _APT_ problem, you may want to open an issue on OpenJDK.
Some more findings: If you add some debug output to your annotation processor,
...
{code:java}
public boolean process(final Set<? extends TypeElement> annotations,
final RoundEnvironment roundEnv) {
System.out.println("Processor ran!");
System.out.println(annotations);
System.out.println(roundEnv);
for (Element element :
roundEnv.getElementsAnnotatedWith(MyFirstAnnotation.class)) {
MyFirstAnnotation firstAnnotation =
element.getAnnotation(MyFirstAnnotation.class);
MySecondAnnotation secondAnnotation =
firstAnnotation.secondAnnotation();
System.out.println(firstAnnotation + " -> " + secondAnnotation);
}
return true;
}
{code}
... it will print only ...
{code:none}
Processor ran!
[org.example.MyFirstAnnotation]
[errorRaised=false, rootElements=[org.example.AnnotatedClass],
processingOver=false]
{code}
... for your current code before throwing the exception, as if
{{FirstAnnotation}} on the class was not even there!
Change your default to something more explicit like...
{code:java}
MySecondAnnotation secondAnnotation() default
@MySecondAnnotation(stringArray = "");
{code}
..., and suddenly it works like a charm on all JDK versions, both on the CLI
and in Maven. The annotation processor then prints:
{code:none}
Processor ran!
[org.example.MyFirstAnnotation]
[errorRaised=false, rootElements=[org.example.AnnotatedClass],
processingOver=false]
@org.example.MyFirstAnnotation([email protected](stringArray={""}))
-> @org.example.MySecondAnnotation(stringArray={""})
Processor ran!
[]
[errorRaised=false, rootElements=[], processingOver=true]
{code}
Interestingly, the processor runs twice, in the second round with
{{processingOver=true}}. I am not an APT expert, so maybe someone else
understands what this means. Either way, it is a JDK tools issue, not a
MCOMPILER one.
was (Author: kriegaex):
FWIW, I cloned the sample project and found out that
* the issue still occurs in Maven Compiler 3.11.0,
* it also occurs on JDKs 17 and 21 and there no combination of source, target
or release (1.8, 11, 17, 21) seems to make it go away,
* the fact that it works on JDK 11 with release 11 seems to be a fluke.
The most important finding, however, is that this issue is *not
MCOMPILER-related at all.* With the same JDK versions and the same compilation
options on the console using _javac_, the very same symptoms reproduce. Again,
I tried 8, 11, 17, 21. I am suggesting to close this issue. If you think that
this is a _javac_ or _APT_ problem, you may want to open an issue on OpenJDK.
Some more findings: If you add some debug output to your annotation processor,
...
{code:java}
public boolean process(final Set<? extends TypeElement> annotations,
final RoundEnvironment roundEnv) {
System.out.println("Processor ran!");
System.out.println(annotations);
System.out.println(roundEnv);
for (Element element :
roundEnv.getElementsAnnotatedWith(MyFirstAnnotation.class)) {
MyFirstAnnotation firstAnnotation =
element.getAnnotation(MyFirstAnnotation.class);
MySecondAnnotation secondAnnotation =
firstAnnotation.secondAnnotation();
System.out.println(firstAnnotation + " -> " + secondAnnotation);
}
return true;
}
{code}
... it will print only ...
{code:none}
Processor ran!
[org.example.MyFirstAnnotation]
[errorRaised=false, rootElements=[org.example.AnnotatedClass],
processingOver=false]
{code}
... for your current code before throwing the exception, as if the second
annotation was not even there!
Change your default to something more explicit like...
{code:java}
MySecondAnnotation secondAnnotation() default
@MySecondAnnotation(stringArray = "");
{code}
..., and suddenly it works like a charm on all JDK versions, both on the CLI
and in Maven. The annotation processor then prints:
{code:none}
Processor ran!
[org.example.MyFirstAnnotation]
[errorRaised=false, rootElements=[org.example.AnnotatedClass],
processingOver=false]
@org.example.MyFirstAnnotation([email protected](stringArray={""}))
-> @org.example.MySecondAnnotation(stringArray={""})
Processor ran!
[]
[errorRaised=false, rootElements=[], processingOver=true]
{code}
Interestingly, the processor runs twice, in the second round with
{{processingOver=true}}. I am not an APT expert, so maybe someone else
understands what this means. Either way, it is a JDK tools issue, not a
MCOMPILER one.
> Annotation processor fails with AnnotationTypeMismatchException on Java 11
> which targets Java 8
> -----------------------------------------------------------------------------------------------
>
> Key: MCOMPILER-424
> URL: https://issues.apache.org/jira/browse/MCOMPILER-424
> Project: Maven Compiler Plugin
> Issue Type: Bug
> Affects Versions: 3.8.1
> Environment: Apache Maven 3.6.3
> Java 11.0.7
> Reporter: Marian Macik
> Priority: Major
>
> When I configure the Maven Compiler Plugin running on Java 11 to target Java
> 8:
> {code:xml}
> <plugin>
> <groupId>org.apache.maven.plugins</groupId>
> <artifactId>maven-compiler-plugin</artifactId>
> <version>3.8.1</version>
> <configuration>
> <source>1.8</source>
> <target>1.8</target>
> </configuration>
> </plugin>
> {code}
> My compilation will fail with
> {{java.lang.annotation.AnnotationTypeMismatchException}} when I use an
> annotation processor.
> I investigated it a little bit and found out that this happens only in a very
> specific case which has to fulfil these criteria:
> 1. One annotation which has the second annotation as a parameter.
> 2. The second annotation has a parameter of type {{String[]}}.
> 3. Java 11 has the compilation target set to Java 8.
> The same scenario works without any issues when I configure the Maven
> Compiler Plugin with {{<release>11</release>}}.
> I debugged the code and when I set the Maven Compiler Plugin to source/target
> 1.8, I noticed changes in the *AnnotationProxyMaker$ValueVisitor#getValue()*
> method. In this case, on the line in the *getValue()* method
> {code:java}
> attr.accept(this);
> {code}
> the *attr* variable holds a *ClassReader$ArrayAttributeProxy* object (so the
> second annotation's String[] parameter is being handled) and then I can see a
> *ClassCastException* thrown inside the
> *ClassReader$ArrayAttributeProxy#accept()* method:
> {code:java}
> public void accept(Visitor v) {
> ((ProxyVisitor)v).visitArrayAttributeProxy(this); }
> {code}
> which says
> {noformat}
> class com.sun.tools.javac.model.AnnotationProxyMaker$ValueVisitor cannot be
> cast to class com.sun.tools.javac.jvm.ClassReader$ProxyVisitor
> (com.sun.tools.javac.model.AnnotationProxyMaker$ValueVisitor and
> com.sun.tools.javac.jvm.ClassReader$ProxyVisitor are in module jdk.compiler
> of loader 'app')
> {noformat}
> so the *Visitor v* (of type *AnnotationProxyMaker$ValueVisitor*) cannot be
> cast to *ClassReader$ProxyVisitor*, which is correct by looking at the source
> code, and then the exception is caught at the
> *{{AnnotationProxyMaker$ValueVisitor#visitCompound()}}* method which handles
> the whole second annotation (which the String[] parameter is a part of).
> After that, it fails with the *AnnotationTypeMismatchException*.
> Now, when I execute this with {{<release>11</release>}}, the *attr* variable
> holds an *Attribute$Array* object and its *accept()* method looks different:
> {code:java}
> public void accept(Visitor v) { v.visitArray(this); }
> {code}
> and the code executes perfectly fine.
> There is a workaround for this and it is pretty simple. You just need to add
> an import of the second annotation on the annotated class being processed by
> the processor, even if just the default value is used. Or, in case the
> annotated class is in the same package as the annotation itself, you just
> need to provide the default value explicitly, see:
> {code:java}
> package org.example;
> /*
> * Uncomment one of these lines and the annotation processor starts working.
> */
> //import org.example.MySecondAnnotation;
> @MyFirstAnnotation(
> //secondAnnotation = @MySecondAnnotation
> )
> public class AnnotatedClass {
> }
> {code}
> Now I don't know if the issue is with the Java compiler or the Maven Compiler
> Plugin, but if it is with the former, you can at least help me to contact the
> Java compiler developers or forward me to the correct Java compiler issue
> tracking system.
> I have also prepared a reproducer which shows this issue. It is available on
> GitHub [1] and includes a short README file with instructions on how to run
> it.
> Thanks for help!
> [1] [https://github.com/MarianMacik/JDK11-annotation-processor-reproducer]
--
This message was sent by Atlassian Jira
(v8.20.10#820010)