Whats'?
SonarQubeで使えるJavaのルールって、SonarQube自身が提供しているのか、それとも他のOSSなどのルールを使っているのか知りたいなぁと思いまして。
結論
すべて、SonarQube自前のルールでした。
SpotBugs、FindSecBugs、PMD、Checkstyleで検出した問題については、インポートが可能だということです。
SonarQube doesn't run your external analyzers or generate reports. It only imports pre-generated reports.
Importing SpotBugs, FindSecBugs, PMD, Checkstyle Issues Reports(※このページはもうメンテナンスされていません)
今回は、その確認の過程を書いていきます。
環境
今回は、SonarQubeサーバー 8.6 Community Editionを対象とします。
SonarQubeで使えるJavaのルール
SonarQubeサーバーで「Rules」から「Java」を選ぶと、Javaに関するルールが605あることが確認できます。
なんとなく、ドキュメントを見るとSpotBugs、FindBugs、FindSecBugs、PMD、Checkstyleが関係していそうな気はします。
External Issues、とは書いていますが…。
Analyzing Source Code / Languages / Java
SonarQube上で見てみても、関係しているのかどうかわかりません。
個別のルールを見ても、やっぱりわかりません。
分類として、Code Smell、Bug、Vulnerability、Security Hotspotがあるのはわかるんですけどね。
Sonar Maven Pluginを見る
こちらのエントリで少し使ってみたので、Sonar Maven Pluginを起点に追ってみましょう。
現時点のSonar Maven Pluginのpom.xml
などを見ても、SpotBugsなどが入っている様子はありません。
どうやら、クライアント側は関係ないようです。
Sonar Java Pluginを見る
いろいろ調べていると、こちらが実体のように思います。
Code Quality and Security for Java
ここで、SonarQubeサーバーのインストールディレクトリにある、lib/extensions
ディレクトリを見てみます。
ちょっと気になります。
$ ll lib/extensions
-rw-r--r--. 1 xxxxx xxxxx 5056472 Dec 9 10:25 sonar-csharp-plugin-8.15.0.24505.jar
-rw-r--r--. 1 xxxxx xxxxx 10627704 Dec 9 10:25 sonar-css-plugin-1.3.1.1642.jar
-rw-r--r--. 1 xxxxx xxxxx 1550044 Dec 9 10:25 sonar-flex-plugin-2.6.0.2294.jar
-rw-r--r--. 1 xxxxx xxxxx 6102054 Dec 9 10:25 sonar-go-plugin-1.8.1.1804.jar
-rw-r--r--. 1 xxxxx xxxxx 823033 Dec 9 10:25 sonar-html-plugin-3.3.0.2534.jar
-rw-r--r--. 1 xxxxx xxxxx 19648 Dec 9 10:25 sonar-jacoco-plugin-1.1.0.898.jar
-rw-r--r--. 1 xxxxx xxxxx 18717478 Dec 9 10:25 sonar-java-plugin-6.9.0.23563.jar
-rw-r--r--. 1 xxxxx xxxxx 19371396 Dec 9 10:25 sonar-javascript-plugin-7.0.1.14561.jar
-rw-r--r--. 1 xxxxx xxxxx 8466805 Dec 9 10:25 sonar-kotlin-plugin-1.8.1.1804.jar
-rw-r--r--. 1 xxxxx xxxxx 5310930 Dec 9 10:25 sonar-php-plugin-3.13.0.6849.jar
-rw-r--r--. 1 xxxxx xxxxx 4527459 Dec 9 10:25 sonar-python-plugin-3.1.0.7619.jar
-rw-r--r--. 1 xxxxx xxxxx 13053290 Dec 9 10:25 sonar-ruby-plugin-1.8.1.1804.jar
-rw-r--r--. 1 xxxxx xxxxx 14687152 Dec 9 10:25 sonar-scala-plugin-1.8.1.1804.jar
-rw-r--r--. 1 xxxxx xxxxx 3760426 Dec 9 10:25 sonar-vbnet-plugin-8.15.0.24505.jar
-rw-r--r--. 1 xxxxx xxxxx 2242738 Dec 9 10:25 sonar-xml-plugin-2.0.1.2020.jar
Community Editionを使っているので、ちょうどサポート対象の15言語分ですね。
SonarQubeサーバーのドキュメントを見ていると、解析はクライアント側でやっているのかな?と思うのですが、
適用するルールはサーバー側で管理しているので、ちょっとわからなくなりますね。
sonar-java-plugin-6.9.0.23563.jar
は、こちらのリポジトリから作られたもののようです。
Code Quality and Security for Java
ちょっと中身を見てみましょう。
$ jar -tvf lib/extensions/sonar-java-plugin-6.9.0.23563.jar | grep -iE 'spotbugs|findbugs|findsecbugs|pmd|checkstyle'
1626 Mon Oct 05 01:32:58 UTC 2020 org/sonar/java/checks/NoCheckstyleTagPresenceCheck.class
1587 Mon Oct 05 01:32:58 UTC 2020 org/sonar/java/checks/NoPmdTagPresenceCheck.class
4548 Mon Oct 05 01:32:58 UTC 2020 org/sonar/java/externalreport/PmdSensor.class
6057 Mon Oct 05 01:32:58 UTC 2020 org/sonar/java/externalreport/CheckstyleXmlReportReader.class
9209 Mon Oct 05 01:32:58 UTC 2020 org/sonar/java/externalreport/PmdXmlReportReader.class
5807 Mon Oct 05 01:32:58 UTC 2020 org/sonar/java/externalreport/SpotBugsSensor.class
511 Mon Oct 05 01:32:58 UTC 2020 org/sonar/java/externalreport/CheckstyleXmlReportReader$IssueConsumer.class
9549 Mon Oct 05 01:32:58 UTC 2020 org/sonar/java/externalreport/SpotBugsXmlReportReader.class
0 Mon Oct 05 01:32:58 UTC 2020 org/sonar/l10n/java/rules/spotbugs/
24823 Mon Oct 05 01:32:06 UTC 2020 org/sonar/l10n/java/rules/spotbugs/findsecbugs-rules.json
76105 Mon Oct 05 01:32:06 UTC 2020 org/sonar/l10n/java/rules/spotbugs/fbcontrib-rules.json
0 Mon Oct 05 01:32:58 UTC 2020 org/sonar/l10n/java/rules/checkstyle/
34405 Mon Oct 05 01:32:06 UTC 2020 org/sonar/l10n/java/rules/checkstyle/rules.json
5829 Mon Oct 05 01:32:58 UTC 2020 org/sonar/java/externalreport/CheckstyleSensor.class
0 Mon Oct 05 01:32:58 UTC 2020 org/sonar/l10n/java/rules/pmd/
61670 Mon Oct 05 01:32:06 UTC 2020 org/sonar/l10n/java/rules/pmd/rules.json
130757 Mon Oct 05 01:32:06 UTC 2020 org/sonar/l10n/java/rules/spotbugs/spotbugs-rules.json
0 Mon Oct 05 01:32:58 UTC 2020 META-INF/maven/com.google.code.findbugs/
0 Mon Oct 05 01:32:58 UTC 2020 META-INF/maven/com.google.code.findbugs/jsr305/
4286 Fri Mar 31 10:21:36 UTC 2017 META-INF/maven/com.google.code.findbugs/jsr305/pom.xml
121 Fri Mar 31 10:55:32 UTC 2017 META-INF/maven/com.google.code.findbugs/jsr305/pom.properties
少し関係ありそうですね。
たとえば、こちら。
抜粋してみます。
[
{
"key": "AM_CREATES_EMPTY_JAR_FILE_ENTRY",
"name": "Bad practice - Creates an empty jar file entry",
"type": "CODE_SMELL",
"severity": "MAJOR",
"url": "https://spotbugs.readthedocs.io/en/latest/bugDescriptions.html#AM_CREATES_EMPTY_JAR_FILE_ENTRY"
},
{
"key": "AM_CREATES_EMPTY_ZIP_FILE_ENTRY",
"name": "Bad practice - Creates an empty zip file entry",
"type": "CODE_SMELL",
"severity": "MAJOR",
"url": "https://spotbugs.readthedocs.io/en/latest/bugDescriptions.html#AM_CREATES_EMPTY_ZIP_FILE_ENTRY"
},
{
"key": "AT_OPERATION_SEQUENCE_ON_CONCURRENT_ABSTRACTION",
"name": "Multi-threading - Sequence of calls to concurrent abstraction may not be atomic",
"type": "BUG",
"severity": "MAJOR",
"url": "https://spotbugs.readthedocs.io/en/latest/bugDescriptions.html#AT_OPERATION_SEQUENCE_ON_CONCURRENT_ABSTRACTION"
},
...
]
type
とルール上の分類が一致しそうですね。
リポジトリをclone
して中身を見てみます。
$ git clone https://github.com/SonarSource/sonar-java.git
$ cd sonar-java
対象のバージョンにcheckout
。
$ git checkout 6.9.0.23563
type
で集計してみます。
$ find external-reports/src/main/resources/org/sonar/l10n/java/rules -name '*.json' | xargs grep '"type"' | perl -wp -e 's!.+("type.+)!$1!' | sort | uniq -c
553 "type": "BUG",
654 "type": "CODE_SMELL",
139 "type": "VULNERABILITY",
多い…。
ファイルパスも一部含めてみましょう。
$ find external-reports/src/main/resources/org/sonar/l10n/java/rules -name '*.json' | xargs grep '"type"' | perl -wp -e 's!.+/(.+/.+) *("type.+)!$1 $2!' | sort | uniq -c
156 checkstyle/rules.json: "type": "CODE_SMELL",
288 pmd/rules.json: "type": "CODE_SMELL",
308 spotbugs/fbcontrib-rules.json: "type": "BUG",
128 spotbugs/findsecbugs-rules.json: "type": "VULNERABILITY",
245 spotbugs/spotbugs-rules.json: "type": "BUG",
210 spotbugs/spotbugs-rules.json: "type": "CODE_SMELL",
11 spotbugs/spotbugs-rules.json: "type": "VULNERABILITY",
うーん、よくわからないですね…。
実際にSonarQubeサーバーが認識しているルールは、ここにあるようです。
Sonar wayプロファイルの定義もありました。
なんですけど、全然わからない名前が並んでいます。
{
"name": "Sonar way",
"ruleKeys": [
"S100",
"S101",
"S106",
"S107",
"S108",
"S110",
"S112",
"S114",
...
このディレクトリ内にあるファイルのほとんどは、自動生成されたもののようです。
実体は、同じプロジェクトのこういうコードでしょうか?
@DeprecatedRuleKey(ruleKey = "S00100", repositoryKey = "squid")
@Rule(key = "S100")
public class BadMethodNameCheck extends IssuableSubscriptionVisitor {
S[数字]
なものを確認してみましょう。
$ grep -rE '"S[0-9]+"' java-checks/src/main/java | perl -wp -e 's!.+(S\d+).+!$1!' | sort -u | wc -l
599
599個ですね。
ここで、SonarQubeのルールを"リポジトリ"という単位別に見れることに気づいたので、見比べてみます。
「SonarQube」が599個。一致します。
つまり、ここにあるのがSonarQubeのルールの実体です。
残りの6個はというと、こちらに定義してあります。
つまり、605個のルールはすべてSonarQube自前のルールでした。
ここでこのページに気づき、あくまでSpotBugs、FindSecBugs、PMD、Checkstyleは「インポート可能なもの」だと認識しました…。
Importing SpotBugs, FindSecBugs, PMD, Checkstyle Issues Reports
なるほど、それで"External Issues"だったんですね。
こちらのページで、インポートするファイルのパスをシステムプロパティで指定できると書いていますが、それが書いてあるのがここですね。
なるほど、すっきりしました。