1、現狀痛點
系統越來越臃腫,開發過程中可能產生的無用代碼增加了系統維護成本。
2、設計思路
2.1、靜態代碼掃描方案
本方案解決靜態代碼下無調用方法掃描,通過ASTParser對靜態文件進行掃描分析,獲取代碼塊來判斷調用關係。
基本步驟及思路
(1)載入本地磁盤項目
(2)循環使用ASTParser解析每個java文件的方法塊,把類名+方法名和方法代碼塊一起落緩存,vm文件單獨落。
分析代碼如下
(3)進行調用關係掃描,再次用ASTParser解析解析每個java文件的方法塊,拿方法名去緩存中根據代碼塊模糊查詢,刨除掉自己之後統計調用次數,次數爲0的可以認爲是殭屍方法,打印出來供參考。
2.2、運行時掃描方案
本方案是藉助jacoco(Java Code Coverage),jacoco本質是一種測試覆蓋率工具,通過asn字節碼增強技術再源代碼中加入探針從而獲取代碼覆蓋率
具體實踐
(1)依賴jacoco.ant
在工程內的pom中引入jar依賴
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.ant</artifactId>
<version>0.8.3</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.9.9</version>
</dependency>
(2)賦能Rest請求
添加一個url地址,通過ant執行dump task用於Dump Coverage文件生成
@RestController
@RequestMapping("/coverage")
public class CoverageController {
@PostMapping("dump")
@NoCheckMenuPermission
public Result<Boolean> dumpCoverageFile() {
DumpTask dumpTask = new DumpTask();
// dump文件地址
dumpTask.setDestfile(new File("/export/Data/coverage/code-cover.exec"));
// 多次dump追加形式
dumpTask.setAppend(true);
// 選一個空閒接口即可
dumpTask.setPort(8840);
// 默認本機
dumpTask.setAddress("127.0.0.1");
dumpTask.execute();
return Result.succeed(true);
}
}
(3)嵌入jacocoagent
java啓動參數添加如下:
#decompress file 解壓依賴,獲得jacocoagent.jar包,避免需要聯繫運維上傳包
jar -xvf $BASEDIR/lib/org.jacoco.agent-0.8.3.jar
-javaagent:$BASEDIR/bin/jacocoagent.jar=includes=com.jdwl.*,output=tcpserver,port=8840,address=127.0.0.1 -Xverify:none
(4)增加配置腳本
/home/admin/clean_export.sh(腳本默認內容上增加了 && $9 != "coverage")
輸出的文件路徑爲/export/Data/coverage/code-cover.exec
(5)下載cover文件
/export/Data/coverage/code-cover.exec目錄下
(6)分析代碼
打開idea -> run -> show coverage data選擇對應的exec文件即可獲取服務端的代碼覆蓋情況。
綠色覆蓋(活躍代碼)
紅色未覆蓋(殭屍代碼)
(7)相關鏈接
3、實現結果
1、啓動工具,選擇工程路徑
2、點擊生成DB,解析代碼載入數據庫
3、點擊掃描,獲取結果