[ 
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:23 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, 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(secondAnnotation=@org.example.MySecondAnnotation(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,
* 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, 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(secondAnnotation=@org.example.MySecondAnnotation(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)

Reply via email to