FindBugs 代碼靜態掃描bug插件的配置和使用

Checkstyle是一款可以幫助開發人員檢查代碼隱藏bug的分析工具; 它可以進行代碼掃描, 產生bug檢測報告, 以便開發人員及時去修復; 使用它可以讓我們的工程代碼質量更高;


常見自動化CI所採用的插件列表

在項目中配置使用FindBugs

在Gradle項目中, 配置使用FindBugs

gradle構建腳本使用groovy

  1. 首先在build.gradle中引入FindBugs插件
// 以外部文件的方式引入gradle插件腳本, 方便對build管理, 不至於膨脹過快
apply from: 'gradle/findbugs.gradle'
  1. 看一下findbugs.gradle文件裏面的內容
apply plugin: 'findbugs'

findbugs {
    // The version of the code quality tool to be used.
    // The most recent version of Checkstyle can be found at https://github.com/checkstyle/checkstyle/releases
    toolVersion = "3.0.1"

    showProgress = true

//    reportsDir = file("${buildDir}/reports/findbugs")

}

tasks.withType(FindBugs) {
    reports {
        xml.enabled false
        html.enabled true
        html.stylesheet resources.text.fromFile('config/findbugs/default.xsl')
    }
}
  1. 上面的config/findbugs/default.xs是FindBugs生成HTML格式bug檢查報告的樣式文件
    文件具體內容可以參考: default.xsl

  2. 在命令行終端執行以下命令對插件進行使用

// 對main-->java包中的java類做檢測
gradlew findbugsMain
// 對test-->java包中的java類做檢測
gradlew findbugsTest

在git管理的項目中, 通過hook執行findbugsMain verify

在項目的根目錄下的.git文件夾下面添加pre-commit文件, 這個hook就會在本地進行git commit前執行

#!/bin/sh
#set -x
# From gist at https://gist.github.com/chadmaughan/5889802

# run the tests with the gradle wrapper for checkstyleMain
./gradlew checkstyleMain

RESULT=$?
# check if checkstyleMain method is success
if ! [ $RESULT == 0 ]; then
  exit $RESULT
fi

# run the tests with the gradle wrapper for findbugsMain
./gradlew findbugsMain

RESULT=$?
# return the './gradlew findbugsMain' exit code
exit $RESULT

初始化本地的hook

因爲hook是放在.git文件夾下的, 而這個文件夾的內容不會被提交到遠程倉庫, 爲了所有開發者都能以安裝的方式初始化所有hook, 那我們弄個統一的腳本在每個人的本地初始化hook

  1. 在項目根目錄下面建一個boot文件(windows下面就是boot.bat)

boot

#/bin/bash

case "$1" in
  "checkstyle")
  open build/reports/checkstyle/main.html
  ;;
  "findbugs")
  open build/reports/findbugs/main.html
  ;;
  "jacoco")
  open build/reports/jacoco/index.html
  ;;
  "init-hook")
   cp hook/pre-commit .git/hooks/pre-commit
   cp hook/pre-push .git/hooks/pre-push
   chmod a+x .git/hooks/pre-commit
   chmod a+x .git/hooks/pre-push
  ;;
esac

boot.bat

@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  boot.bat for windows
@rem
@rem ##########################################################################

set OPTION=%1%
set DIRNAME=%~dp0

if "%OPTION%" == "checkstyle" (
  start %DIRNAME%build\reports\checkstyle\main.html
)

if "%OPTION%" == "findbugs" (
  start %DIRNAME%build\reports\findbugs\main.html
)

if "%OPTION%" == "jacoco" (
  start %DIRNAME%build\reports\jacoco\index.html
)

if "%OPTION%" == "init-hook" (
  copy "hook\pre-commit" ".git\hooks\pre-commit"
  copy "hook\pre-push" ".git\hooks\pre-push"
  echo init-hook execute success
)
  1. 執行腳本初始化方法
// linux
boot init-hook
// windows
boot.bat init-hook

本地進行git commit時會自動執行pre-commit裏面的內容

關於findbugs所能檢測的bug條目具體見: bugDescriptions
這裏我們故意寫一個bug(在一個class裏面繼承接口Cloneable, 但沒實現它的clone方法), 看看檢測報告

 git commit -m "xxx"
Scanning archives (56 / 56)
2 analysis passes to perform
Pass 1: Analyzing classes (172 / 172) - 100% complete
Pass 2: Analyzing classes (23 / 23) - 100% complete
Done with analysis
The following classes needed for analysis were missing:
  java.lang.Object
  java.lang.Cloneable
  java.lang.RuntimeException
  java.lang.Enum
  java.util.ArrayList
  java.util.List
  java.lang.String
  java.io.InputStream
  java.lang.Throwable
  java.io.PrintWriter
  java.util.concurrent.ConcurrentHashMap
  java.util.Collection
  java.util.stream.Stream
  java.util.stream.Collectors
  java.lang.StringBuilder
  java.lang.Long
  java.lang.NoSuchFieldError
  java.lang.UnsatisfiedLinkError
  java.io.Serializable
  java.lang.invoke.LambdaMetafactory
  java.lang.invoke.MethodHandles$Lookup
  java.lang.invoke.MethodHandles
  java.io.IOException
  java.lang.IllegalAccessError
  java.lang.IncompatibleClassChangeError
  java.lang.Error
  java.lang.NullPointerException
  java.lang.AbstractMethodError

Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
See https://docs.gradle.org/4.8.1/userguide/command_line_interface.html#sec:command_line_warnings
3 actionable tasks: 1 executed, 2 up-to-date

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':findbugsMain'.
> FindBugs rule violations were found. See the report at: file:///E:/project/gavin/moon-boot/build/reports/findbugs/main.html

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 4s

報告如圖
findbugs report

Over!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章