- SonarQube 9.9.1-community
- Maven 3.9.1
これはなに
SonarQubeよくわからん人向け。
「何できるもんなんだろ」とか「現場でSonarQube使ってるものの、設定とか影響範囲わからなくて怖い」とか、色々とあると思う。ローカルでいじくれるとイメージも湧きやすいしハードル下がるかなと思って書いた。
あとJaCoCo周りはあちこちでなんやかんやあるので。
準備
SonarQube
Dockerで。
docker run -p 9000:9000 --rm sonarqube:9.9.1-community
- http://localhost:9000 ひらく。
admin/adminでログイン- パスワード設定画面になるのでパスワードを
hogeに変更
通常はTokenを作成するが、ここではSonarQubeの設定も揮発するコンテナで動かしてるのでやらない。
他の形
https://www.sonarsource.com/products/sonarqube/downloads/
Docker使わないならダウンロードして解凍してでもできる。けど「とりあえず触る」にはちょっと面倒だよね。
手元に入れるの面倒ならオープンソースならSonarCloudが無料で使えるけど、このブログのタイトルから外れるので書かない。
アプリケーション(ない場合)
https://start.spring.io とかで spring-boot-starter-web の pom.xml とってきて準備。
▼pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>dev.irof.suburi</groupId>
<artifactId>spring-maven-sonar</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>すぶり</name>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
SpringBootである必要は何一つない。
見ての通り(本エントリはMavenある程度わかる人を想定しています)、SonarQubeに関する記述は pom.xml にはありません。
なのでもし手元に手頃なMavenプロジェクトあるならそのまま使えばいいです。
以降は ./mvnw 使ってるけど、パス通ってるMaven使うなら mvn でもいいし、 mvn wrapper:wrapper 叩いてからでもいい。
実行
./mvnw clean package sonar:sonar -Dsonar.login=admin -Dsonar.password=hoge
さっきパスワードを hoge に変えたから sonar.password はそれにしてる。他のにしてたら変えてね。
トークン使ってみたり別ユーザー作ってみたりしていじってみましょう。
説明
sonar-maven-plugin は特別扱いされてるので、 pom.xml に何も書かなくても sonar:sonar で実行できちゃいます。
とはいえ設定書きたいとかバージョン制御したいとかあると思うんで、本番では書いた方がいいかもですね。
sonar.login / sonar.password とかは前述の通り。SonarQubeのURLはデフォルト http://localhost:9000 なので何も書いてないだけです。
この辺りは設定したくなるはずなので、ドキュメント読んで settings.xml に書くとか、実行シェルに書くとかしていきませう。
ちなみにプラグインのソースは https://github.com/SonarSource/sonar-scanner-maven にあります。
なお clean package とかしなくても sonar:sonar だけでスキャンはしてくれます。
でも普通はテストの通ったものをスキャンすると思うし、テスト結果もSonarQubeにのっけときたいと思うし。
確認
前述の pom.xml を使ったなら http://localhost:9000/projects に「すぶり」ってプロジェクトができてるはず。

この名前は /project/name になる。
あとは好きにどうぞ。
もう一歩: カバレッジ
たとえばカバレッジをSonarQubeに取り込みたいなら、 jacoco-maven-plugin 入れてやってください。
...
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.8</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<!-- verify -->
<id>default-report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
prepare-agent がテストとか実行する前にJaCoCoのagentを設定するもの。 phase は指定しなくてもいい感じの場所( initialize )に入ります。
report がSonarQubeも取り込める形のJaCoCoのレポート(XML)を出力するものです。これ実行してあげないとSonarQubeのカバレッジは永久に0%と表示されます。
<execution> で <phase> を書かない場合、 jacoco:report は verify で実行されます。
先に挙げたコマンドだと package までしか実行してないので、JaCoCoのレポートは出力されません。
てことでこう。
./mvnw clean verify sonar:sonar -Dsonar.login=admin -Dsonar.password=hoge
<execution> 書かずに jacoco:report を手で実行してあげてもいいですけどね。
./mvnw clean package jacoco:report sonar:sonar -Dsonar.login=admin -Dsonar.password=hoge
分けるならこうでも。
./mvnw clean package ./mvnw jacoco:report ./mvnw sonar:sonar -Dsonar.login=admin -Dsonar.password=hoge
test でJaCoCoのファイル target/jacoco.exec が出来て、それを元に target/site/jacoco/* を作るのが jacoco:report です。
うまく取り込めてると sonar:sonar の時に以下のように Importing 1 report(s) が出ます。
[INFO] Sensor JaCoCo XML Report Importer [jacoco] [INFO] 'sonar.coverage.jacoco.xmlReportPaths' is not defined. Using default locations: target/site/jacoco/jacoco.xml,target/site/jacoco-it/jacoco.xml,build/reports/jacoco/test/jacocoTestReport.xml [INFO] Importing 1 report(s). Turn your logs in debug mode in order to see the exhaustive list. [INFO] Sensor JaCoCo XML Report Importer [jacoco] (done) | time=7ms
ダメだったらこんな風に出るはず。
[INFO] Sensor JaCoCo XML Report Importer [jacoco] [INFO] 'sonar.coverage.jacoco.xmlReportPaths' is not defined. Using default locations: target/site/jacoco/jacoco.xml,target/site/jacoco-it/jacoco.xml,build/reports/jacoco/test/jacocoTestReport.xml [INFO] No report imported, no coverage information will be imported by JaCoCo XML Report Importer [INFO] Sensor JaCoCo XML Report Importer [jacoco] (done) | time=1ms
少し前のSonarQubeは jacoco.exec を読んだのだけど、XML読むようにちょっと前に変わった。まぁ気持ちはわかる。
注意
- SonarQubeのフッタに警告表示されてるけど、組み込みデータベース使ってるんでコンテナ落としたらデータ消えます。あくまで実験用。
- SonarQubeのプロジェクトページ開いたら警告表示されてるけど、
sonar.passwordはそのうち使えなくなるらしいです。なのでここでは9.9.1-communityとバージョン固定してます。「これから使っていくためにとりあえず触る」目的ならltsとかlatestとか使う方がいいと思うよ。
併せて読む必要がない
JaCoCoで検索してもこの記事しかなかった。あんま書いてないのね私。SonarQubeは長年の付き合いなのに一記事も書いてなかった……。