SonarQubeをJavaプロジェクトで利用

## SonarQubeを純粋なJavaプロジェクトで利用した際のメモ
SonarQubeを使おうとした際にMavenやGradleから利用する記事はたくさん見つかりましたが、純粋なJavaのプログラムで使うにはどうすればいいか、意外と中々見つからなかったので、メモを残しておきます。

### 利用したソフトウェア
* JDK17
* SonarQube 10.5.1
* sonar-scanner-5.0.1
* Eclipse IDE 2024-03

### 処理のポイント
* 手動でJacocoレポートを作成して、それをsonar-scanner.batを走らせてSonarQubeに渡す

### Javaプログラムソースで単体テストとカバレッジを確認
純粋なJavaのプロジェクトをEclipseで作成して、単体テストとカバレッジを実行する。

以下がアプリケーションのソース側のAppクラス。

```java:App.java
package com.aksys;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class AppTest {
    @Test
    void testHelloWorld() {
        App app = new App();
        assertEquals("Hello world!!", app.helloWorld());
    }

    @Test
    void testMain() {
    	App.main(new String[]{});
        assertTrue(true);
    }
}
```

これをJUnitで単体テストするAppTestクラス。
```java:AppTest.java
package com.aksys;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class AppTest {
    @Test
    void testHelloWorld() {
        App app = new App();
        assertEquals("Hello world!!", app.helloWorld());
    }

    @Test
    void testMain() {
    	App.main(new String[]{});
        assertTrue(true);
    }
}
```

### Coverageレポートを作成してSonarQubeにレポートを渡す準備をする
EclipseのメニューからCoverageレポートを作成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790222/ad9e40c2-da4f-fa40-2ba9-d2f8dad874df.png)

カバレッジの結果が出力されるので、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790222/97cfb9cd-f892-6ac8-aa52-6ad18f91129d.png)

カバレッジの結果をレポートにしてSonarQubeが読み取れる形式と場所にエクスポートする。
実施済みのカバレッジを右クリック、Export Sessionを選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790222/83ee432b-0b16-946f-6de5-35d81ef2cf8c.png)

Export画面でFormatにXML fileを選択して、Destinationに出力先を記入する。
この出力先をsonar-project.properties（後述）のsonar.coverage.jacoco.xmlReportPathsと一致させる必要がある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790222/f2130864-59f5-8fe3-0476-393fd498e3a6.png)

### SonarCubeでローカルプロジェクトを作成する
Project keyはsonar-project.properties（後述）sonar.projectKeyと一致させる。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790222/e8ae74b6-2736-ffb4-84bf-fdc2cec584b1.jpeg)

![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790222/9c429a69-f2d6-a4ec-ae80-14d4dfbf7fe9.jpeg)

SonarCubeでトークンを作成 -> Locallyを選択
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790222/7893d5d2-2d93-2cff-9ae8-a3426cefdc6f.png)

トークン名を入れてGenerateを押下
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790222/84ce2bc1-b693-ede9-3031-7bccb62fb8b4.png)

トークン(sqp_xxxx)が生成されるので手元にコピーしておく
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790222/9e158bad-a633-35f5-fd74-0a12ffd69457.png)

プロジェクトが作成された
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790222/1b7a33d1-8ffa-cbdc-b652-b00d34756584.png)

### Sonar Scannerを使う場合の設定ファイルsonar-project.propertiesを準備する

```properties:sonar-project.properties
# SonarQubeサーバー
sonar.host.url=http://localhost:9000
sonar.token=sqp_... <注）SonarQubeで生成したトークンを入力>

# SonarQubeのプロジェクト情報
sonar.projectKey=HelloJavaSonar
# Javaのソースコードの場所
sonar.sources=C:/Git/GitHub/HelloJavaSonar/src
# Javaのテストコードの場所
sonar.tests=C:/Git/GitHub/HelloJavaSonar/test
# Javaのコンパイル結果の場所
sonar.java.binaries=C:/Git/GitHub/HelloJavaSonar/bin
# Junit結果
sonar.junit.reportPaths=bin/test-results/test/*
# Jacoco結果
sonar.coverage.jacoco.xmlReportPaths=C:/Git/GitHub/HelloJavaSonar/report/report.xml
# 各種ライブラリの場所 Eclipseが参照するライブラリ群でOK
sonar.java.libraries=C:/Users/xxxxx/.p2/pool/plugins/**/*.jar
sonar.java.test.libraries=C:/Users/xxxxx/.p2/pool/plugins/**/*.jar
```

sonar-scanner.batを実行
```
> sonar-scanner.bat
INFO: Scanner configuration file: C:\Program Files\SonarQube\sonar-scanner-5.0.1.3006-windows\bin\..\conf\sonar-scanner.properties
INFO: Project root configuration file: C:\Git\GitHub\HelloJavaSonar\sonar-project.properties
INFO: SonarScanner 5.0.1.3006
…
INFO: ANALYSIS SUCCESSFUL, you can find the results at: http://localhost:9000/dashboard?id=HelloJavaSonar
INFO: Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
INFO: More about the report processing at http://localhost:9000/api/ce/task?id=37ea3ed0-b627-4623-906f-7220d0a21f30
INFO: Analysis total time: 7.368 s
INFO: ------------------------------------------------------------------------
INFO: EXECUTION SUCCESS
INFO: ------------------------------------------------------------------------
INFO: Total time: 8.157s
INFO: Final Memory: 18M/74M
INFO: ------------------------------------------------------------------------
Exception in thread "Thread-0" java.lang.NoClassDefFoundError: ch/qos/logback/classic/spi/ThrowableProxy
```
EXECUTION SUCCESSが出ていれば、分析終了！
※なぜか最後に出るExceptionはここでは無視します。。

### SonarQubeを確認
[http://localhost:9000/dashboard?id=HelloJavaSonar](http://localhost:9000/dashboard?id=HelloJavaSonar)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790222/645150c3-5f7c-a757-c36e-eb469a9560b9.png)

カバレッジの結果も確認できることが分かります。