1

I've got the classes below. Two annotations (AnnotA and AnnotB), a class 'Child.java' (with @AnnotA) and its' parent 'Base.java' (with @AnnotB).

When compiling Child.java, my annotation processor repors AnnotA but it doesn't report the annotations (AnnotB) found in Base.java.

AnnotA.java

import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
public @interface AnnotA
    {
    }

AnnotB.java

import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
public @interface AnnotB
    {
    }

Base.java

@AnnotB
public class Base
    {
    }

Child.java

@AnnotA
public class Child extends Base
    {
    }

MyProc.java

import javax.annotation.processing.*;
import java.lang.annotation.*;
import javax.lang.model.*;
import javax.lang.model.element.*;
import javax.tools.*;
import java.util.*;
import java.util.stream.*;

@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class MyProc  extends AbstractProcessor
    {
    @Override
    public Set<String> getSupportedAnnotationTypes()  {
        final Set<String> set = new HashSet<>();
        set.add("AnnotA");
        set.add("AnnotB");
        return set;
        }
    @Override
    public boolean process(final Set<? extends TypeElement> annotations,
        final RoundEnvironment roundEnv
        ) {
        roundEnv.getElementsAnnotatedWith(AnnotA.class).stream().
            forEach(E->{System.err.println("AnnotA>>" + E + " "+ E.getAnnotation(AnnotA.class));});

        roundEnv.getElementsAnnotatedWith(AnnotB.class).stream().
            forEach(E->{System.err.println("AnnotB>>" + E + " "+ E.getAnnotation(AnnotB.class));});
        return true;
        }
    }

Here is the compilation process and it's output, as your can see, there is no message about AnnotB while Parent.java is a parent of Child.java

rm -rf tmp
mkdir -p tmp/META-INF/services
javac -d tmp MyProc.java
echo "MyProc" > tmp/META-INF/services/javax.annotation.processing.Processor
jar cvf myproc.jar -C tmp .
added manifest
ignoring entry META-INF/
adding: META-INF/services/(in = 0) (out= 0)(stored 0%)
adding: META-INF/services/javax.annotation.processing.Processor(in = 7) (out= 9)(deflated -28%)
adding: AnnotB.class(in = 363) (out= 221)(deflated 39%)
adding: MyProc.class(in = 2512) (out= 1118)(deflated 55%)
adding: AnnotA.class(in = 363) (out= 221)(deflated 39%)
##
mkdir -p tmp
javac -processorpath myproc.jar -d tmp Child.java
AnnotA>>Child @AnnotA()
warning: Implicitly compiled files were not subject to annotation processing.
  Use -implicit to specify a policy for implicit compilation.
1 warning
rm -rf tmp

what's wrong with this code ? Thanks .

Pierre
  • 34,472
  • 31
  • 113
  • 192
  • As far as I know this is the expected behaviour - annotations are not automatically inherited from superclasses. When you find a class, you would have to inspect its superclasses explicitly if you want to know an annotation is present somewhere in the class hierarchy. – Jesper May 29 '17 at 14:14
  • longer story after I tried to add '@Inherited' to AnnotB / I want to include a java source code in the jar each time the class is annotated with `@IncludeInJar` , but it doesn't see @IncludeInJar when this annotation is in the parent class. – Pierre May 29 '17 at 14:52

1 Answers1

1

Use @Inherited to inherit annotations.

How to use @inherited annotation in Java?

sercasti
  • 550
  • 3
  • 7
  • thanks, I've added `@Inherited` to AnnotB . The output is now `AnnotA>>Child @AnnotA() AnnotB>>Child @AnnotB()` but I would like to see `AnnotA>>Child @AnnotA() AnnotB>>Base @AnnotB()` (longer story, I want to include a java source code each time the class is annotated with `@IncludeInJar` ) – Pierre May 29 '17 at 14:51
  • If you examine the child class you get information about the child class. If you want information about the base type, examine the base type. – Lew Bloch May 29 '17 at 16:45
  • Why does this not work with interfaces? Only concrete classes and abstract classes? – searchengine27 Jul 29 '22 at 16:21