【问题标题】:Proper way for getting annotations of Java-Methods in custom Sonar rules在自定义声纳规则中获取 Java 方法注释的正确方法
【发布时间】:2017-06-13 19:51:41
【问题描述】:

我尝试编写自定义声纳规则 (Java),并努力寻找正确的方法来获取调用的 Java 方法的注释。 此规则应检测对标记为@VisibleForTesting 的方法和字段的非法访问。从生产代码访问这些元素是非法的,但从同一类访问是合法的。 我的第一种方法是实现BaseTreeVisitor.visitMethodInvocation(MethodInvocationTree) 并使用所属符号的元数据:

  • 获取注释:methodInvocationSymbol.metadata().annotations()
  • 分析每个AnnotationInstance(注解类)及其所有者(注解包)的符号名称

只要其他类调用该方法,它就可以很好地工作。当调用在同一个类中时 - 注释名称和包被设置为!unknownSymbol!

我还尝试了另一种方法:分析AnnotationTreeIdentifierTree(在BaseTreeVisitor.visitMethodInvocation(MethodInvocationTree))内部,但是我找不到如何获取注解的包名的方法。

我使用 sonar-java-plugin 3.7.1 和 sonar-plugin-api 5.1。

代码提交在这个mvn / Eclipse projectUnexpectedAccessCheckTest 包含 2 个用例。 “InvokedFromOtherClass”运行良好。 InvokedFromSameClass 通过了测试,但这只是偶然发生的——注释没有被正确检测到。 它产生这个输出:

[main] DEBUG d.t.s.p.vft.checks.IsAnAnnotation - Checking Annotation. 
    Expected [com.google.common.annotations.VisibleForTesting] 
    got [.!unknownSymbol!]

正确的运行用例会产生这样的结果:

[main] DEBUG d.t.s.p.vft.checks.IsAnAnnotation - Checking Annotation. 
    Expected [com.google.common.annotations.VisibleForTesting] 
    got [com.google.common.annotations.VisibleForTesting]

你有什么提示吗?

【问题讨论】:

  • 能否请您准确说明您正在使用的 sonar-java 插件版本?如果我正确地回答了您的问题,那么您的问题是何时要检查在与其声明相同的源文件中调用的方法?您描述的第一种方法应该可以工作,如果没有,那么很可能该方法没有解决。你能分享一个不起作用的示例案例吗?
  • @benzonico 感谢您的快速回答!我使用 3.7.1 的 sonar-java-plugin 和 5.1 的 sonar-plugin-api
  • 如果对您有帮助,请点赞并接受答案。
  • 您共享了代码,但这还不清楚,您想要检测的模式究竟是什么,哪些没有按预期工作?

标签: java sonarqube


【解决方案1】:

首选第一种方法,它应该适用于每个方法调用,即使在同一个类中也是如此。

如果它不起作用,则可能意味着调用的方法没有从语义解析(这就是为什么将符号设置为未知的原因,分析器在涉及泛型时有一些关于方法调用的错误)。 为了向您指出正确的票证,需要一个示例。

关于您对语法树的评论:语法树中的标识符将不包含有关包的信息(因为它的名称泄露了它,它只涉及 syntax ;))。但是,您可以使用以下方法从源中查找注释的类型:

annotationTree.annotationType().symbolType().is("com.mypackage.MyAnnotation")

在运行扫描时确保预期的二进制文件位于 Classpath 中(请参阅 sonar.java.binaries 属性,或者如果您使用 Maven,则使用 maven-dependency-plugin)。

【讨论】:

  • 它似乎不是这样工作的,至少在我的配置中是这样。在github.com/arxes-tolina/sonar-plugins 中,我提交了带有调试输出的MisuseOfVisibleForTestingCheck。运行MisuseOfVisibleForTestingCheckTest 只会产生[main] DEBUG d.t.s.p.v.c.MisuseOfVisibleForTestingCheck - VisibleForTesting found: false 行......知道为什么会这样吗?
  • 您尝试测试的注释的字节码应该通过sonar.java.binaries属性在分析的类路径中可用
  • 这条线索帮助我理解,为什么在 org.sonar.samples:java-custom-rules 中有一个额外的执行 maven-dependency-plugin :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 2016-05-26
  • 2016-06-03
相关资源
最近更新 更多