[JAVA] La rétention peut ne pas être disponible pour les annotations SOURCE lors de l'exécution du traitement des annotations dans l'EDI

Lors de l'exécution du traitement des annotations dans l'EDI, les informations d'annotation définies par @Retention (RetentionPolicy.SOURCE) peuvent ne pas être obtenues dans certaines conditions.

environnement

OS

Windows 10

Java

openjdk 10.0.2

Eclipse

Photon (4.8.0)Pleiades

IntelliJ

IntelliJ IDEA 2018.2.3 (Community Edition)

Gradle

Gradle 4.10

Symptômes

Code source

Structure du projet


|-foo/
| `-src/main/java/
|   `-sample/foo/
|     |-Fizz.java
|     `-Buzz.java
|
|-bar/
| |-src/main/java/
| | `-sample/bar/
| |   |-MyRuntimeRetention.java
| |   |-MyClassRetention.java
| |   |-MySourceRetention.java
| |   `-MyProcessor.java
| |
| `-src/main/resources/
|   `-META-INF/services
|     `-javax.annotation.processing.Processor
|
|-build.gradle
`-settings.gradle

--Multi-projet de foo, bar --Un projet dans lequel bar implémente le traitement des annotations --foo est un projet qui utilise le traitement d'annotation de bar --MyRuntimeRetention.java, MyClassRetention.java, MySourceRetention.java sont leurs propres annotations et Retention est défini sur la valeur correspondant au nom.

MyRuntimeRetention.java


package sample.bar;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyRuntimeRetention {
}

MyClassRetention.java


package sample.bar;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface MyClassRetention {
}

MySourceRetention.java


package sample.bar;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface MySourceRetention {
}

--Une classe dans laquelle MyProcessor.java implémente le traitement des annotations

MyProcessor.java


package sample.bar;

import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.tools.Diagnostic.Kind;

public class MyProcessor extends AbstractProcessor {

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        Elements elements = this.processingEnv.getElementUtils();
        
        if (!annotations.isEmpty()) {
            this.printAnnotations(elements.getTypeElement("sample.foo.Fizz"));
            this.printAnnotations(elements.getTypeElement("sample.foo.Buzz"));
        }
        
        return true;
    }
    
    private void printAnnotations(TypeElement element) {
        element.getAnnotationMirrors().forEach(annotation -> {
            this.processingEnv.getMessager().printMessage(Kind.NOTE, element.getSimpleName() + " : " + annotation);
        });
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.RELEASE_10;
    }
    
    @Override
    public Set<String> getSupportedAnnotationTypes() {
        return Set.of(MySourceRetention.class.getCanonicalName());
    }
}

Fizz.java


package sample.foo;

import sample.bar.MyClassRetention;
import sample.bar.MyRuntimeRetention;
import sample.bar.MySourceRetention;

@MyRuntimeRetention
@MyClassRetention
@MySourceRetention
public class Fizz {
}

Buzz.java


package sample.foo;

import sample.bar.MyClassRetention;
import sample.bar.MyRuntimeRetention;
import sample.bar.MySourceRetention;

@MyRuntimeRetention
@MyClassRetention
@MySourceRetention
public class Buzz {
}

Traitement à effectuer

Dans cet état, modifiez uniquement la classe ** Fizz et exécutez ** la compilation. Ensuite, le résultat sera différent lors de l'exécution dans Gradle et lors de l'exécution dans l'IDE (Eclipse, IntelliJ).

Lors de l'exécution sur Gradle

> gradle :foo:compileJava

Mise en garde:Fizz : @sample.bar.MyRuntimeRetention
Mise en garde:Fizz : @sample.bar.MyClassRetention
Mise en garde:Fizz : @sample.bar.MySourceRetention
Mise en garde:Buzz : @sample.bar.MyRuntimeRetention
Mise en garde:Buzz : @sample.bar.MyClassRetention
Mise en garde:Buzz : @sample.bar.MySourceRetention

Lors de l'exécution dans Eclipse

apt.jpg

Lors de l'exécution sur IntelliJ

apt.jpg

Vous pouvez également l'obtenir dans l'EDI en modifiant Buzz

--Modifiez non seulement la classe Fizz mais aussi la classe Buzz, puis exécutez la construction pour faire fonctionner le processus d'annotation.

Eclipse apt.jpg

IntelliJ apt.jpg

Devinez ce qui s'est passé

--Lorsque Retention est défini sur SOURCE, Les informations d'annotation ne restent pas dans le fichier de classe /RetentionPolicy.html#SOURCE)

Conclusion (devinez)

--Lorsque le traitement des annotations fonctionne dans IDE (Eclipse, IntelliJ), il semble que vous ne puissiez pas obtenir les informations de l'annotation dont Retention est SOURCE, qui est définie dans la classe sans modification.

Recommended Posts

La rétention peut ne pas être disponible pour les annotations SOURCE lors de l'exécution du traitement des annotations dans l'EDI
Lorsque le projet n'est pas affiché dans eclipse
Traitement lorsqu'un ID qui n'existe pas dans la base de données est entré dans l'URL
Comment définir quand "Le constructeur Empty () n'est pas visible" se produit dans junit
Lorsque j'exécute la commande source dans le Makefile d'Ubuntu, j'obtiens "source: command not found"