Can't get working my annotation custom rule on sonarqube server

Hello,

i wrote a rule to check if a method is annotated with a configured annotation. I can sucessfully test it using a test in my local project but once i try to use it in the server the symbol.metadata().isAnnotatedWith fails.
I’ve added some warn logs; the line ‘Detected method name’ i can see it in my local test but not during the scanning process
Can anyone give my some ideas why? Here is my rule code

import java.util.Arrays;
import java.util.List;

import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.sonar.plugins.java.api.JavaFileScanner;
import org.sonar.plugins.java.api.JavaFileScannerContext;
import org.sonar.plugins.java.api.semantic.Symbol;
import org.sonar.plugins.java.api.semantic.Symbol.MethodSymbol;
import org.sonar.plugins.java.api.semantic.SymbolMetadata.AnnotationValue;
import org.sonar.plugins.java.api.tree.BaseTreeVisitor;
import org.sonar.plugins.java.api.tree.MethodTree;

@Rule(key = "AnnotationPresentRule")
public class AnnotationPresentRule extends BaseTreeVisitor implements JavaFileScanner {
    
    private static final Logger LOG = Loggers.get(AnnotationPresentRule.class);

    public static final String DEFAULT_NAME_VALUE = "javax.ws.rs.Consumes";
    public static final String DEFAULT_CONTAINS_VALUE = "application/json;charset=UTF-8";

    private JavaFileScannerContext context;

    public AnnotationPresentRule() {
        super();
        LOG.warn("AnnotationPresentRule new instance!");
    }


    @RuleProperty(defaultValue = DEFAULT_NAME_VALUE, description = "Name of the annotation to check, without the prefix @, for instance 'javax.ws.rs.Consumes'")
    private String name;

    @RuleProperty(defaultValue = DEFAULT_CONTAINS_VALUE, description = "The value annotation contains, without the prefix @, for instance 'application/json;charset=UTF-8;charset=UTF-8'")
    private String contains;

    @Override
    public void scanFile(JavaFileScannerContext context) {
        this.context = context;
        scan(context.getTree());
    }

    @Override
    public void visitMethod(MethodTree tree) {
        MethodSymbol symbol = tree.symbol();
        LOG.warn("Checking method name {} annotated with {} which has to contains {}", symbol.name(), getName(), getContains());
        if (symbol.metadata().isAnnotatedWith(getName())) {
            LOG.warn("Detected method name {} annotated with {} ", symbol.name(), getName());
            if (isAnnotatedWithContains(symbol)) {
                context.reportIssue(this, tree, String.format("Detected using of annotation @%s with value %s", getName(), getContains()));
            }
        }
        // The call to the super implementation allows to continue the visit
        // of
        // the AST.
        // Be careful to always call this method to visit every node of the
        // tree.
        super.visitMethod(tree);

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getContains() {
        return contains;
    }

    public void setContains(String contains) {
        this.contains = contains;
    }

    private boolean isAnnotatedWithContains(Symbol checkSymbol) {
        List<AnnotationValue> valuesForAnnotation = checkSymbol.metadata().valuesForAnnotation(getName());
        if (valuesForAnnotation == null) {
            return false;
        }
        boolean b = valuesForAnnotation.stream().filter(annotationValue -> "value".equals(annotationValue.name())).anyMatch(
                    annotationValue -> {
                        if(annotationValue.value() instanceof Object[]) {
                            return Arrays.stream((Object[]) annotationValue.value()).anyMatch(aValue -> getContains().equals(aValue));
                        } else {
                            return getContains().equals(annotationValue.value());
                        }
                    }
                );
        return b;
    }
}

I’ve invastigated further and i’ve seen that i had some missing jar. Now i added them and it works.

I seem to have a similar problem, do you mind sharing which jar you had to include and where? In your project or in sonarqube-s plugins?

Hello Karlo, i’ve simply specified a sonar.java.libraries inside the properties file i fed to analyzer