Monday, March 14, 2022

[SOLVED] How to declare a warning on field with AspectJ

Issue

I want to declare a warning on all fields Annotated with @org.jboss.weld.context.ejb.Ejb in AspectJ.

But I do not find a way how to select that field.

I guess the aspect should be something like that:

public aspect WrongEjbAnnotationWarningAspect {
   declare warning :
       within(com.queomedia..*) &&
       ??? (@org.jboss.weld.context.ejb.Ejb)
       : "WrongEjbAnnotationErrorAspect: use javax.ejb.EJB instead of weld Ejb!";
}

Or is it impossible to declare warnings on fields at all?


Solution

The only field pointcuts I see are for get and set. This makes sense because aspects are primarily about executing code. Declaring compiler warnings is sortof a nice side benefit. If we just talk about a field, independent of the use of that field, when would the pointcut be hit? I think you should be able to do what you want with the Annotation Processing Tool instead of AspectJ. Here is a first stab at it, mostly copied from the example on the tool's web page linked above.

public class EmitWarningsForEjbAnnotations implements AnnotationProcessorFactory {
    // Process any set of annotations
    private static final Collection<String> supportedAnnotations
        = unmodifiableCollection(Arrays.asList("*"));

    // No supported options
    private static final Collection<String> supportedOptions = emptySet();

    public Collection<String> supportedAnnotationTypes() {
        return supportedAnnotations;
    }

    public Collection<String> supportedOptions() {
        return supportedOptions;
    }

    public AnnotationProcessor getProcessorFor(
            Set<AnnotationTypeDeclaration> atds,
            AnnotationProcessorEnvironment env) {
        return new EjbAnnotationProcessor(env);
    }

    private static class EjbAnnotationProcessor implements AnnotationProcessor {
        private final AnnotationProcessorEnvironment env;

        EjbAnnotationProcessor(AnnotationProcessorEnvironment env) {
            this.env = env;
        }

        public void process() {
            for (TypeDeclaration typeDecl : env.getSpecifiedTypeDeclarations())
                typeDecl.accept(new ListClassVisitor());
        }

        private static class ListClassVisitor extends SimpleDeclarationVisitor {
            public void visitClassDeclaration(ClassDeclaration d) {
                for (FieldDeclaration fd : d.getFields()) {
                    fd.getAnnotation(org.jboss.weld.context.ejb.Ejb.class);
                }

            }
        }
    }
}


Answered By - John Watts
Answer Checked By - Robin (WPSolving Admin)