使用Java插件运行SonarQube 6.4 4.9.0.9858.I编写了一条规则来确认内部开发的maven项目正在导入包含各种库的标准版本号的父POM文件。我已成功编码,单元测试,部署和激活质量配置文件中的规则。但是,当我使用该质量配置文件对maven项目运行扫描时,不会触发该规则。
我可以看到类org.sonar.java.xml.XmlAnalyzer
决定为一般的xml文件和特别是pom文件触发哪些规则。具体来说,XMLAnalyzer选择要应用于pom.xml文件的org.sonar.java.xml.maven.PomChecks
实例的所有规则。
问题是,我的自定义规则是类org.sonar.java.xml.maven.PomCheck
的一个实例,如下所示
import org.sonar.java.xml.maven.PomCheck;
...snip...
@Rule( key = "UseParentPOM" )
public class UseParentPOM implements PomCheck {
...snip...
这"实现了PomCheck"方法正是java-plugin提供的规则如GroupIdNamingConventionCheck
将自己定义为PomChecks - 并且在扫描运行期间选择了 。我已经检查过我是否使用SQ安装所使用的相同插件库版本编译我的自定义规则。并且运行sonar-scanner-debug并附加到正在运行的进程显示我的UseParentPOM规则实际上是XMLAnalyzer用于搜索候选规则的访问者列表。但是PomCheck"访客实例的具体情况。返回false。因此,我的规则没有添加到pom规则列表中,并且在扫描pom.xml时没有被触发。
显然,我的规则类不是XMLAnalyzer所期望的PomCheck,但是我做错了什么才能使它成为PomCheck的一个实例?
更新
进一步的挖掘表明,提供类java-frontend-4.9.0.9858.jar的.jar文件同时位于基本的sonar-java-plugin-4.9.0.9858.jar和我的custom-java-rules- 1.0-SNAPSHOT.jar。我的调试运行显示,SonarQube似乎为扩展目录中的每个插件.jar启动了单独的类加载器。因此,就SQ而言,确实存在2' org.sonar.java.xml.maven.PomCheck'类。因此我的原始问题。
我因此尝试从我的自定义规则.jar中删除java-frontend-4.9.0.9858.jar(以及PomCheck类),将所有声纳相关依赖项作为< provided>进行范围调整。我希望得到的SQ进程会有1个PomCheck类来统治它们。然而,实际结果是SQ甚至无法启动,因为无法找到(TA DA)类PomCheck而尝试加载我的自定义规则类时Web服务器进程失败。
我认为这已经达到了一个不可解决的困境 - 如果我在我的自定义.jar中包含PomCheck,SQ就会很好但不能将我的自定义规则识别为"真正的" PomCheck。如果我没有在我的自定义.jar中包含PomCheck,那么SQ根本就不会开始。所以现在我真的陷入了困境 - 请帮忙。
其他详细信息
Re:Nicholas B的请求,注册我的自定义规则的代码如下
public final class MyRulesList {
...snip...
public static List<Class<? extends JavaCheck>> getChecks() {
return ImmutableList.<Class<? extends JavaCheck>>builder().addAll(getJavaChecks()).addAll(getJavaTestChecks()).build();
}
public static List<Class<? extends JavaCheck>> getJavaChecks() {
return ImmutableList.<Class<? extends JavaCheck>>builder()
.add(PackageNaming.class)
.add(LoggingLevels.class)
.add(UseParentPOM.class)
.build();
}
... snip ...
}
此代码直接从Writing Custom Java Rules 101站点复制。据我所知,所有3个自定义类都已正确注册 - 我可以在Web控制台UI中看到它们并将它们添加到Quality Gate。规则PackageNaming / LoggingLevels和规则UseParentPOM之间的唯一区别是UseParentPOM实现PomCheck接口,而不是JavaCheck。但是,由于类PomCheck只是类JavaCheck的包装器,这似乎是注册UseParentPom类的正确方法,例如就像任何其他JavaCheck一样。但也许不是吗?
答案 0 :(得分:1)
简而言之:SonarJava不支持自定义检查POM文件(即自定义 PomCheck )。
更多详情
每Java custom rules tutorial,必须通过将自定义规则提供给getJavaChecks
(针对源文件检查)或getJavaTestChecks
(针对测试文件进行检查)来激活自定义规则。问题是 pom.xml 文件不属于这两个类别中的任何一个,而是属于“XML文件桶”,对其进行了特定的规则检查。
一个可视化的好方法是浏览SonarJava的CheckList.java,注意专用的getXmlChecks
和getMavenChecks
。这些是对扫描器索引的XML文件实际运行的检查。
具体而言
虽然您可以自由地向getJavaChecks
或getJavaTestChecks
添加自定义规则,但SonarJava API不支持向getMavenChecks
添加规则(您可以尝试,但它会有效地执行任何操作)。您的整体分析非常明确,但事实是只有包含 api 的软件包才能通过类加载器(example)访问,而不是 PomCheck 。
我不知道在这方面有任何改变的计划。
'在框外思考'建议
SonarXML支持使用XPath表达式的自定义规则(请参阅extension guide)。通过一些XPath体操,您可以考虑扩展规则 xml:XPathCheck - 跟踪违反XPath规则。