# SonarQube Community Edition 9.9 LTS 使用 sonar-pdf-report 匯出 PDF 報告 > [name=Daniel Huang][time=Mon, Dec 4, 2023 9:37 AM][color=#ef53a4] [TOC] ## 一、前言 上週五我發了一篇 [SonarQube Community Edition 使用 SonarQube CNES Report Plugin 匯出 PDF 報告](/NzvlPzqWT3OJuzg2T4kKcw),分享 SonarQube 的 PDF 匯出方式。在前言的部分有提到,Ivan 大寫的 [iThome: SonarQube 如何產生 PDF 分析報告](https://ithelp.ithome.com.tw/articles/10313246) 裡分享的外掛 [sleroy/sonar-pdf-report](https://github.com/sleroy/sonar-pdf-report) 因 SonarQube 版本不符 (9.9 LTS) 無法使用。 但在嘗試將專案重新建置後發現,只要更新 Plugin 專案的相依套件版本,並注意檢測專案使用的 Token 是否為全域的 User Token 就可以使用了。 ## 二、實作紀錄 這個章節會帶大家看一下整個實作的過程紀錄,如果只是要看怎麼使用這個 Plugin 可以跳到 [2-3 將 jar 複製到 SonarQube 安裝路徑下](#2-3-將-jar-複製到-SonarQube-安裝路徑下)。 ### 2-1 製作 Plugin 的 jar 檔 從 [sleroy/sonar-pdf-report](https://github.com/sleroy/sonar-pdf-report) 下載 Plugin 專案,並使用 IntelliJ 開啟。 ![open sleroy version](https://hackmd.io/_uploads/BJAmw2qSp.png) :::success 我所使用的 IntelliJ 版本與環境設定 ```! IntelliJ IDEA 2023.2.5 (Community Edition) Build #IC-232.10227.8, built on November 9, 2023 Runtime version: 17.0.9+7-b1000.46 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Windows 10.0 GC: G1 Young Generation, G1 Old Generation Memory: 4090M Cores: 16 Registry: ide.experimental.ui=true Non-Bundled Plugins: IdeaVIM (2.7.5) com.jetbrains.packagesearch.intellij-plugin (232.9921.28) org.jetbrains.kotlin (232-1.9.21-release-633-IJ10072.27) org.jetbrains.compose.desktop.ide (1.5.11) Kotlin: 232-1.9.21-release-633-IJ10072.27 ``` ![image](https://hackmd.io/_uploads/HknyHn5r6.png) ::: :::info 💡 補充: 為什麼選擇 IntelliJ 開啟專案? 如果你有看 Ivan 大分享的文章,會發現當中是下載 Apache Maven 執行指令打包。 但這次的實作中,因為筆者本身就有安裝 IntelliJ ,且當中就有安裝 Maven Plugin,因此就不用另外下載 Apache Maven。 ![image](https://hackmd.io/_uploads/rJpb435Sp.png) ::: ### 2-2 執行 Maven `package` 指令建立 jar 點選 IDE 右方的工具列中的 M 符號,開啟 Maven 視窗,並點選節點下的 `Lifecycle/package` 執行[打包](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Packaging)。 ![image](https://hackmd.io/_uploads/B1TiD35Sa.png) 這時候會發現打包失敗,錯誤訊息如下: ```! class lombok.javac.apt.LombokProcessor (in unnamed module @0x7cecd959) cannot access class com.sun.tools.javac.processing.JavacProcessingEnvironment (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.processing to unnamed module @0x7cecd959 ``` [爬文](https://stackoverflow.com/a/66981165/9982091)後發現是相依套件的版本問題。把 `pom.xml` 底下的這個 `dependency` 更新到 1.8.28 就可以正常打包了。 ```xml= <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.28</version> </dependency> ``` 打包成功後可以在專案資料夾下的 `/target` 資料夾找到 `sonar-pdf-report-****.jar`。 ![packaged jar](https://hackmd.io/_uploads/H1YS_fiS6.png) :::danger 🚨 有需要的話可以直接 Pull [我在 Github 上的 Fork dh-46/sonar-pdf-report](https://github.com/dh-46/sonar-pdf-report),這是已經有更新過相依套件的版本。 ::: ### 2-3 將 jar 複製到 SonarQube 安裝路徑下 :::warning 💡 略過打包步驟的讀者,可以從[這裡](https://github.com/dh-46/sonar-pdf-report/releases/tag/1.5.2)下載已打包好的 `sonar-pdf-report-1.5.2.jar`。 ::: 將打包好的 `jar` 複製到 SonarQube 資料夾下的 `extensions/plugins` 資料夾中。 ![image](https://hackmd.io/_uploads/By96q35Hp.png) ### 2-4 啟動 SonarQube 並更新被測專案的 Token ![image](https://hackmd.io/_uploads/HymgepqBT.png) 如果執行檢測專案的指令中所用的 Token,是在建置專案(如下圖)時所建立的。 ![image](https://hackmd.io/_uploads/rkGu7p5BT.png) 將會需要到 `Administration/Security/Users` 中,新增一個帳號層級的新 Token,替換掉目前使用的專案 Token。 ![image](https://hackmd.io/_uploads/rkXb-TqHp.png) :::info 🤔 為什麼要更新被測專案的 Token? 測試過程中發現,如果是使用一開始在 SonarQube 建立檢測專案的 Token,產製 PDF 時會出現 `Exception in initializeProject()` 的錯誤訊息。 細看後會發現是呼叫 SonarQube 的 API 時,API 回應 403 的錯誤。 ```= INFO: Could not find files for the given pattern(s). Exception in initializeProject() org.sonarqube.ws.client.HttpException: Error 403 on http://localhost:9000/api/components/show?component=npm-guide : {"errors":[{"msg":"Insufficient privileges"}]} at org.sonarqube.ws.client.BaseResponse.failIfNotSuccessful(BaseResponse.java:36) at org.sonarqube.ws.client.BaseService.call(BaseService.java:51) at org.sonarqube.ws.client.BaseService.call(BaseService.java:46) at org.sonarqube.ws.client.components.ComponentsService.show(ComponentsService.java:111) at com.cybage.sonar.report.pdf.builder.ProjectBuilder.initializeProject(ProjectBuilder.java:67) // ... Exception in PDFReport java.lang.NullPointerException: Cannot invoke "com.cybage.sonar.report.pdf.entity.Measures.containsMeasure(String)" because "this.measures" is null at com.cybage.sonar.report.pdf.entity.Project.getMeasure(Project.java:52) at com.cybage.sonar.report.pdf.ExecutivePDFReporter.printFrontPage(ExecutivePDFReporter.java:268) // ... ``` 爬文 ([API authentication issue with tokens - insufficient privileges](https://community.sonarsource.com/t/api-authentication-issue-with-tokens-insufficient-privileges/68753/5)) 後發現**其實是 Token 權限的問題**。在建立 SonarQube 專案時的 Token 在執行分析的時候,PDF Plugin 也會拿來呼叫 SonarQube 的 API 取得專案資料。但是這個 Token 不知為何會沒有讀取權限。所以需要重新在 User 帳號下產一個新 Token 才能使用。 ::: ### 2-5 執行檢測 (以 Android Studio 為例) ![image](https://hackmd.io/_uploads/Sy8LITcS6.png) 在開啟受測專案的 IDE 上執行檢測,成功後產出的 PDF ,會儲存在檢測的專案資料夾下。 以 Android 來說,會在 `/{專案}/app/build/sonar` 中。 > BTW 我測試的時候,不知道為什麼在 Windows 10 的檔案總管裡,`sonar` 資料夾預設是隱藏的。如果你發現找不到輸出結果,可以修改資料夾顯示設定再找找看。 > ![image](https://hackmd.io/_uploads/ryBhzVPSp.png) > [name=Daniel Huang][color=#6bd7ef] 最終產出的 PDF 會是如下方截圖的這種格式: ![image](https://hackmd.io/_uploads/SkQy1A9S6.png) ## 三、結語 相較於上次分享的 [CNES Report Plugin](/NzvlPzqWT3OJuzg2T4kKcw),Sonar PDF Report 執行上麻煩許多。如果沒有特殊需求或是 SonarQube 版本上的限制,個人會建議使用有完整社群支援的 CNES。另外,CNES 的 Plugin 有著 Sonar PDF Report 沒有的自訂 Template 功能,對於有發行文件需求的使用者來說,應該會比較方便吧~ 以上就是今天的分享,內容如有錯誤或疏漏,歡迎留言回饋與指教,謝謝您的耐心閱讀。 :::success 📢 本文同步發表在 [iT 邦幫忙](https://ithelp.ithome.com.tw/articles/10340887) :::