原文链接:Introduction — spotbugs 4.8.3 documentation
FindBugs改名叫SpotBugs。
SpotBugs运行需要JRE(JDK)版本>1.8.0。可以分析大于1.8版本的JDK编译的代码,java11以及更高版本的处于试用阶段。不支持过期的jdk编译的java代码,例如JDK10,9,7以及更低的版本。
规则描述:
SpotBugs可以检查400多种bug。
详细描述:Bug descriptions — spotbugs 4.8.3 documentation
分类:Bad practice/Correctness/Experimental/Internationalization/Malicious code vulnerability/Multithreaded correctness/Bogus random noise/Performance/Performance//security/Dodgy code
BAD_PRACTICE(不良实践):违反推荐和基本的编码实践。示例包括哈希码和相等性问题,可克隆惯用法,丢弃异常,可序列化问题,以及误用 finalize。
CORRECTNESS(缺陷):开发人员未意思到的错误。
EXPERIMENTAL(实验性的):实验性且未经充分审查的错误模式。
I18N(国际化):与国际化和区域设置有关的代码缺陷
MALICIOUS_CODE(恶意代码):容易受到不受信任代码攻击的代码
MT_CORRECTNESS(MT缺陷):与线程、锁和volatile相关的代码缺陷
NOISE(噪音):虚假的随机噪音:旨在作为数据挖掘实验中的控制因素,而不是用于发现软件中实际的错误。
PERFORMANCE():代码可能不是错误的,但可能效率低下。
SECURITY():使用不受信任的输入方式可能会产生远程可利用的安全漏洞。
STYLE(规范):代码混乱、异常或以容易导致错误的方式编写。示例包括无效的本地变量存储、switch穿透、未确认的类型转换以及对已知为null的值进行冗余的null检查。在之前的SpotBugs版本中,此类别被称为“Style”。
工具使用:
https://github.com/spotbugs/spotbugs/releases/download/4.8.3/spotbugs-4.8.3.zip
https://github.com/spotbugs/spotbugs/releases/download/4.8.3/spotbugs-4.8.3.tgz
下载后解压缩,配置环境变量SPOTBUGS_HOME为spotbugs的安装目录。
jar包启动
命令格式
java [JVM arguments] -jar %SPOTBUGS_HOME%/lib/spotbugs.jar options...
命令实例
java \
-Xmx3072m \
-Duser.language=en \
-Dfindbugs.debug=true \
-Dfindbugs.de.comment=true \
-jar ./spotbugs-4.8.3/lib/spotbugs.jar \
-textui \
-effort:min \
-home ./spotbugs-4.8.3 \
-sarif=./report.sarif.json \
./be-analyzed/defect-mgmt-api-1.0.0.jar
交互方式设置
-gui:图形界面方式运行
-textui:命令行模式运行
-version:软件版本
-help:帮助信息
-gui1:旧版图形界面
jvm参数设置
-XmxNNm: 最大堆内存。
-Dname=value: gui语言设置,ja日语。可设置Analysis Properties以及开启debug模式。
脚本启动
命令格式
$SPOTBUGS_HOME/bin/spotbugs options...
C:\My Directory>%SPOTBUGS_HOME%\bin\spotbugs.bat options...
命令实例
./spotbugs-4.8.3/bin/spotbugs -textui \
-javahome ~/jdk/jdk1.8.0_202 \
-jvmArgs "-Duser.language=en" \
-maxHeap 3072 \
-debug \
-property "findbugs.de.comment=true" \
-property "findbugs.nullderef.assumensp=false" \
-effort:min \
-home ./spotbugs-4.8.3 \
-sarif=./report.sarif.json \
./be-analyzed/defect-mgmt-api-1.0.0.jar
交互方式设置
-gui:图形界面方式运行
-textui:命令行模式运行
-version:软件版本
-help:帮助信息
-gui1:旧版图形界面
包装脚本参数设置
-jvmArgs: jvm参数
-javahome: 工具运行时使用的jdk
-maxHeap:jvm堆内存
-debug:开启debug模式
-property:“name=value”,系统参数设置。Analysis Properties是通过系统参数去设置的。
分析控制参数
直接jar包执行,通过-Dname=value设置。包装脚本设置通过-property设置。
参数名 | 值 | 描述 |
---|---|---|
findbugs.assertionmethods | 逗号分隔的完全限定方法名称列表:例如,“com.foo.MyClass.checkAssertion” | 该属性指定用于检查程序断言的方法的名称。指定这些方法允许空指针解引用错误检测器避免针对由断言方法检查的值报告虚假警告。 |
findbugs.de.comment | true or false | 如果设置为true,DroppedException检测器会扫描源代码以查找空catch块的注释,如果找到,则不会报告警告。 |
findbugs.maskedfields.locals | true or false | 如果设置为true,则对遮盖字段的局部变量发出低优先级警告。默认值为false。 |
findbugs.nullderef.assumensp | true or false | 未使用(意图:如果设置为true,则空指针解引用检测器假定从方法返回的任何引用值或在参数中传递给方法的任何引用值可能为null。默认值为false。请注意,启用此属性很可能会导致产生大量的虚假警告。) |
findbugs.refcomp.reportAll | true or false | 如果设置为true,则报告所有使用==和!=运算符的可疑引用比较。如果设置为false,则每个方法只发出一个此类警告。默认值为false。 |
findbugs.sf.comment | true or false | 如果设置为true,则SwitchFallthrough检测器仅会针对源代码中没有包含“fall”或“nobreak”单词的注释的情况报告警告。(必须使用准确的源路径才能使此功能正常工作。)这有助于找到可能是无意的开关穿透的情况。 |
工具参数设置
这里的参数在以脚本方式或者可执行jar包方式运行都可以使用。
gui和textui通用参数
-effort[:min|less|default|more|max]
分析工作量级别。min->max,分析时间越来越长,分析问题精度越来越高,消耗内存越来越多。默认more
Flags in FindBugs.java | Description | min | less | more | max |
---|---|---|---|---|---|
Accurate Exceptions | Determine (1) what exceptions can be thrown on exception edges, (2) which,catch blocks are reachable, and (3) which exception edges carry only, “implicit” runtime exceptions. | ✔ | ✔ | ✔ | |
Model Instanceof | Model the effect of instanceof checks in type analysis | ✔ | ✔ | ✔ | |
Track Guaranteed Value Derefs in Null Pointer Analysis | In the null pointer analysis, track null values that are guaranteed to be, dereferenced on some (non-implicit-exception) path. | ✔ | ✔ | ||
Track Value Numbers in Null Pointer Analysis | In the null pointer analysis, track value numbers that are known to be, null. This allows us to not lose track of null values that are not, currently in the stack frame but might be in a heap location where the, value is recoverable by redundant load elimination or forward, substitution. | ✔ | ✔ | ||
Interprocedural Analysis | Enable interprocedural analysis for application classes. | ✔ | ✔ | ||
Interprocedural Analysis of Referenced Classes | Enable interprocedural analysis for referenced classes (non-application classes). | ✔ | |||
Conserve Space | Try to conserve space at the expense of precision. e.g. Prune unconditional exception thrower edges for control flow graph analysis, to reduce memory footprint. | ✔ | |||
Skip Huge Methods | Skip method analysis if length of its bytecode is too long (6,000). | ✔ | ✔ | ✔ |
-project project
指定要分析的项目。一个由GUI 界面创建的目文件。通常它的扩展名为 .fb 或 .fbp。该文件无法由-textui方式生成。fbp文件内容结构如下:
<?xml version="1.0" encoding="UTF-8"?>
<Project projectName="test">
<!-- 分析目标 -->
<Jar>./be-analyzed/xxx.jar</Jar>
<!-- 分析目标依赖 -->
<AuxClasspathEntry>./be-analyzed-depend/HikariCP-5.0.1.jar</AuxClasspathEntry>
<AuxClasspathEntry>./be-analyzed-depend/angus-activation-2.0.1.jar</AuxClasspathEntry>
<!-- 源码目录 -->
<SrcDir>./src/main/java</SrcDir>
</Project>
-pluginList <jar1[;jar2…]>
加载spotbugs的插件。
-home <home directory>
指定SpotBugs的安装目录。
-adjustExperimental
实验性的Bug Patterns优先级较低
-workHard
确保effort模式至少是“more”。
-conserveSpace
与 -effort:min 相同(用于向后兼容)。
GUI参数
-look:plastic|gtk|native
设置gui风格。
Text UI 参数
-sortByClass=filepath
按类名对报告的bug实例进行排序。
从SpotBugs4.5.0开始,这个参数直接配置成报告的存放路径。可以同时输出多种格式的报告。
-xml=spotbugs.xml -sortByClass=spotbugs.txt
-include filterFile.xml
只报告与filterFile.xml指定的过滤器匹配的错误实例。
-exclude filterFile.xml
报告除了匹配filterFile.xml指定的过滤器之外的所有错误实例。
-onlyAnalyze
com.foobar.MyClass,com.foobar.mypkg.,!com.foobar.mypkg.ExcludedClass*
限制查找给定逗号分隔的类和包的错误。与过滤不同,此选项避免在未明确匹配的类和包上运行分析:对于大型项目,这可能大大减少运行分析所需的时间。(但是,如果不在整个应用程序上运行某些检测器,则可能会产生不准确的结果。)
com.foobar.MyClass:指定分析类。
com.foobar.mypkg.*:指定分析某个包下的所有类。
com.foobar.mypkg.-:分析当前以及子目录的类。
!com.foobar.mypkg : 不分析指定的类或目录。
-low
报告所有的bug
-medium
默认设置。报告中高优先级的bug。
-high
报告高优先级的bug。
-relaxed
宽松报告模式,减少误报
-xml=filepath
输出xml格式的报告,可以配合-xml:withMessages选项使用,报告中将会增加易读的问题描述。
-html=filepath
输出html格式报告。提供多种报告样式。通过以下配置需要使用的样式。
-html:plain.xsl 没有使用js和dom,适用于低版本浏览器和打印。
-html:fancy.xsl 使用了js、dom、css。
-html:fancy-hist.xsl fancy的的升级版。
-sarif=filepath
生成sarif(2.1.0版本)格式报告。
-emacs=filepath
生成Emacs格式报告。
-xdocs=filepath
生成用于与Apache Maven一起使用的xdoc XML格式的错误报告。
-nested:true|false
此选项启用或禁用扫描要分析的文件和目录列表中找到的嵌套jar和zip文件。默认情况下,启用扫描嵌套的jar/zip文件。要禁用它,请在命令行参数中添加-nested:false。
-auxclasspath classpath
为分析设置辅助类路径。这个类路径应该包括所有jar文件和目录,这些文件和目录中包含的类是正在分析的程序的一部分,但是您不希望分析这些类的错误。一般为项目依赖的第三方jar包
-auxclasspathFromInput
通过标准输入设置辅助类路径,一行设置一个。
-auxclasspathFromFile filepath
通过文件设置辅助类路径,一行设置一个。
-analyzeFromFile filepath
通过文件读取被分析对象,一行设置一条(文件或者目录)
-userPrefs edu.umd.cs.findbugs.core.prefs
设置用户首选项,相同设置按读取到配置的顺序,后面覆盖前面。例如eclipse项目中的配置文件edu.umd.cs.findbugs.core.prefs。false选项应该是会执行分析,但是报告中不显示。内容如下:
#FindBugs User Preferences
#Wed Sep 20 09:51:48 AKDT 2017
cloud_id=edu.umd.cs.findbugs.cloud.doNothingCloud
detectorAppendingToAnObjectOutputStream=AppendingToAnObjectOutputStream|true
detectorAtomicityProblem=AtomicityProblem|true
detectorBadAppletConstructor=BadAppletConstructor|false
detectorBadResultSetAccess=BadResultSetAccess|true
detectorBadSyntaxForRegularExpression=BadSyntaxForRegularExpression|true
detectorBadUseOfReturnValue=BadUseOfReturnValue|true
detectorBadlyOverriddenAdapter=BadlyOverriddenAdapter|true
detectorBooleanReturnNull=BooleanReturnNull|true
detectorCallToUnsupportedMethod=CallToUnsupportedMethod|false
detectorCheckExpectedWarnings=CheckExpectedWarnings|false
detectorCheckImmutableAnnotation=CheckImmutableAnnotation|true
detectorCheckRelaxingNullnessAnnotation=CheckRelaxingNullnessAnnotation|true
detectorCheckTypeQualifiers=CheckTypeQualifiers|true
detectorCloneIdiom=CloneIdiom|true
detectorComparatorIdiom=ComparatorIdiom|true
detectorConfusedInheritance=ConfusedInheritance|true
detectorConfusionBetweenInheritedAndOuterMethod=ConfusionBetweenInheritedAndOuterMethod|true
detectorCovariantArrayAssignment=CovariantArrayAssignment|false
detectorCrossSiteScripting=CrossSiteScripting|true
detectorDefaultEncodingDetector=DefaultEncodingDetector|true
detectorDoInsideDoPrivileged=DoInsideDoPrivileged|true
detectorDontCatchIllegalMonitorStateException=DontCatchIllegalMonitorStateException|true
detectorDontIgnoreResultOfPutIfAbsent=DontIgnoreResultOfPutIfAbsent|true
detectorDontUseEnum=DontUseEnum|true
detectorDroppedException=DroppedException|true
detectorDumbMethodInvocations=DumbMethodInvocations|true
detectorDumbMethods=DumbMethods|true
detectorDuplicateBranches=DuplicateBranches|true
detectorEmptyZipFileEntry=EmptyZipFileEntry|false
detectorEqualsOperandShouldHaveClassCompatibleWithThis=EqualsOperandShouldHaveClassCompatibleWithThis|true
detectorExplicitSerialization=ExplicitSerialization|true
detectorFinalizerNullsFields=FinalizerNullsFields|true
detectorFindBadCast2=FindBadCast2|true
detectorFindBadForLoop=FindBadForLoop|true
detectorFindCircularDependencies=FindCircularDependencies|false
detectorFindComparatorProblems=FindComparatorProblems|true
detectorFindDeadLocalStores=FindDeadLocalStores|true
detectorFindDoubleCheck=FindDoubleCheck|true
detectorFindEmptySynchronizedBlock=FindEmptySynchronizedBlock|true
detectorFindFieldSelfAssignment=FindFieldSelfAssignment|true
detectorFindFinalizeInvocations=FindFinalizeInvocations|true
detectorFindFloatEquality=FindFloatEquality|true
detectorFindHEmismatch=FindHEmismatch|true
detectorFindInconsistentSync2=FindInconsistentSync2|true
detectorFindJSR166LockMonitorenter=FindJSR166LockMonitorenter|true
detectorFindLocalSelfAssignment2=FindLocalSelfAssignment2|true
detectorFindMaskedFields=FindMaskedFields|true
detectorFindMismatchedWaitOrNotify=FindMismatchedWaitOrNotify|true
detectorFindNakedNotify=FindNakedNotify|true
detectorFindNonShortCircuit=FindNonShortCircuit|true
detectorFindNullDeref=FindNullDeref|true
detectorFindNullDerefsInvolvingNonShortCircuitEvaluation=FindNullDerefsInvolvingNonShortCircuitEvaluation|true
detectorFindOpenStream=FindOpenStream|true
detectorFindPuzzlers=FindPuzzlers|true
detectorFindRefComparison=FindRefComparison|true
detectorFindReturnRef=FindReturnRef|true
detectorFindRoughConstants=FindRoughConstants|true
detectorFindRunInvocations=FindRunInvocations|true
detectorFindSelfComparison=FindSelfComparison|true
detectorFindSelfComparison2=FindSelfComparison2|true
detectorFindSleepWithLockHeld=FindSleepWithLockHeld|true
detectorFindSpinLoop=FindSpinLoop|true
detectorFindSqlInjection=FindSqlInjection|true
detectorFindTwoLockWait=FindTwoLockWait|true
detectorFindUncalledPrivateMethods=FindUncalledPrivateMethods|true
detectorFindUnconditionalWait=FindUnconditionalWait|true
detectorFindUninitializedGet=FindUninitializedGet|true
detectorFindUnrelatedTypesInGenericContainer=FindUnrelatedTypesInGenericContainer|true
detectorFindUnreleasedLock=FindUnreleasedLock|true
detectorFindUnsatisfiedObligation=FindUnsatisfiedObligation|true
detectorFindUnsyncGet=FindUnsyncGet|true
detectorFindUseOfNonSerializableValue=FindUseOfNonSerializableValue|true
detectorFindUselessControlFlow=FindUselessControlFlow|true
detectorFindUselessObjects=FindUselessObjects|true
detectorFormatStringChecker=FormatStringChecker|true
detectorHugeSharedStringConstants=HugeSharedStringConstants|true
detectorIDivResultCastToDouble=IDivResultCastToDouble|true
detectorIncompatMask=IncompatMask|true
detectorInconsistentAnnotations=InconsistentAnnotations|true
detectorInefficientIndexOf=InefficientIndexOf|false
detectorInefficientInitializationInsideLoop=InefficientInitializationInsideLoop|false
detectorInefficientMemberAccess=InefficientMemberAccess|false
detectorInefficientToArray=InefficientToArray|false
detectorInfiniteLoop=InfiniteLoop|true
detectorInfiniteRecursiveLoop=InfiniteRecursiveLoop|true
detectorInheritanceUnsafeGetResource=InheritanceUnsafeGetResource|true
detectorInitializationChain=InitializationChain|true
detectorInitializeNonnullFieldsInConstructor=InitializeNonnullFieldsInConstructor|true
detectorInstantiateStaticClass=InstantiateStaticClass|true
detectorIntCast2LongAsInstant=IntCast2LongAsInstant|true
detectorInvalidJUnitTest=InvalidJUnitTest|true
detectorIteratorIdioms=IteratorIdioms|true
detectorLazyInit=LazyInit|true
detectorLoadOfKnownNullValue=LoadOfKnownNullValue|true
detectorLostLoggerDueToWeakReference=LostLoggerDueToWeakReference|true
detectorMethodReturnCheck=MethodReturnCheck|true
detectorMultithreadedInstanceAccess=MultithreadedInstanceAccess|true
detectorMutableEnum=MutableEnum|true
detectorMutableLock=MutableLock|true
detectorMutableStaticFields=MutableStaticFields|true
detectorNaming=Naming|true
detectorNoteUnconditionalParamDerefs=NoteUnconditionalParamDerefs|true
detectorNumberConstructor=NumberConstructor|true
detectorOptionalReturnNull=OptionalReturnNull|true
detectorOverridingEqualsNotSymmetrical=OverridingEqualsNotSymmetrical|true
detectorPreferZeroLengthArrays=PreferZeroLengthArrays|true
detectorPublicSemaphores=PublicSemaphores|false
detectorQuestionableBooleanAssignment=QuestionableBooleanAssignment|true
detectorReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass=ReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass|true
detectorReadReturnShouldBeChecked=ReadReturnShouldBeChecked|true
detectorRedundantConditions=RedundantConditions|true
detectorRedundantInterfaces=RedundantInterfaces|true
detectorRepeatedConditionals=RepeatedConditionals|true
detectorRuntimeExceptionCapture=RuntimeExceptionCapture|true
detectorSerializableIdiom=SerializableIdiom|true
detectorStartInConstructor=StartInConstructor|true
detectorStaticCalendarDetector=StaticCalendarDetector|true
detectorStringConcatenation=StringConcatenation|true
detectorSuperfluousInstanceOf=SuperfluousInstanceOf|true
detectorSuspiciousThreadInterrupted=SuspiciousThreadInterrupted|true
detectorSwitchFallthrough=SwitchFallthrough|true
detectorSynchronizationOnSharedBuiltinConstant=SynchronizationOnSharedBuiltinConstant|true
detectorSynchronizeAndNullCheckField=SynchronizeAndNullCheckField|true
detectorSynchronizeOnClassLiteralNotGetClass=SynchronizeOnClassLiteralNotGetClass|true
detectorSynchronizingOnContentsOfFieldToProtectField=SynchronizingOnContentsOfFieldToProtectField|true
detectorURLProblems=URLProblems|true
detectorUncallableMethodOfAnonymousClass=UncallableMethodOfAnonymousClass|true
detectorUnnecessaryMath=UnnecessaryMath|true
detectorUnreadFields=UnreadFields|true
detectorUselessSubclassMethod=UselessSubclassMethod|false
detectorVarArgsProblems=VarArgsProblems|true
detectorVolatileUsage=VolatileUsage|true
detectorWaitInLoop=WaitInLoop|true
detectorWrongMapIterator=WrongMapIterator|true
detectorXMLFactoryBypass=XMLFactoryBypass|true
detector_threshold=3
effort=max
excludefilter0=findbugsExclude.xml|true
filter_settings=Low|BAD_PRACTICE,CORRECTNESS,MT_CORRECTNESS,PERFORMANCE,STYLE|false|20
filter_settings_neg=MALICIOUS_CODE,SECURITY,EXPERIMENTAL,NOISE,I18N|
run_at_full_build=false
-showPlugins
显示soptbugs检测到的可用插件。
输出控制选项
-timestampNow
设置结果的时间戳为当前时间。
-quiet
忽略错误信息
-longBugCodes
报告中显示问题的长代码。试了没效果
-progress
在命令窗口显示进度。
-release
设置被分析应用的发布名称。没效果
-maxRank rank
设置报告中问题的最低级别。设置为0-n,数字越小输出的问题越少。
-dontCombineWarnings
不要合并仅行号不同的警告。
-train outputDir
保存训练数据(实验);输出目录默认为' . '。
-useTraining inputDir
使用训练数据(实验数据);输入dir默认为' . '。
-redoAnalysis filename
使用先前分析中的配置重做分析。 不知道如何使用
-sourceInfo filename
指定源信息文件(字段/类的行号)。 不知道如何使用
-projectName project name
项目的描述性名称。不知道如何使用
-reanalyze filename
在提供的文件中重做分析。 不知道如何使用
输出过滤选项
-bugCategories cat1[,cat2…]
只输出给定类别的问题。
-excludeBugs baseline bugs
排除在基线xml输出中也报告的错误。 参数为一个过滤文件。
-applySuppression
排除任何与从fbp文件加载的抑制过滤器匹配的错误。
检测器(访问者)配置选项
-visitors v1[,v2…]
运行指定的visitors。【OverridingMethodsMustInvokeSuperDetector】 【FindRoughConstants】 【FunctionsThatMightBeMistakenForProcedures】等。
-omitVisitors v1[,v2…]
忽略指定的visitors。
-chooseVisitors +v1,-v2,…
选择性的开启/禁用detectors
-choosePlugins +p1,-p2,…
选择性的开启/禁用插件
-adjustPriority v1=(raise|lower)[,…]
调整给定visitor告警等级。
项目配置选项
-sourcepath source path
设置被分析class文件的源文件。
-exitcode
设置分析程序的退出码。
-noClassOk
未找到任何被分析的class时不输出waring信息。
-xargs
从标准输入而不是命令行获取classfiles/jarfiles列表。
-bugReporters name,name2,-name3
Bug报告装饰符显式启用/禁用
-printConfiguration
打印配置并退出,不运行分析。测试时未执行分析,但是也未打印出任何信息。
-textui参数
findbugs [general options] -textui [command line options...] [jar/zip/class files, directories...]
General options:
-jvmArgs args Pass args to JVM
-maxHeap size Maximum Java heap size in megabytes (default=768)
-javahome <dir> Specify location of JRE
General SpotBugs options:
-project <project> analyze given project
-home <home directory> specify SpotBugs home directory
-pluginList <jar1[:jar2...]> specify list of plugin Jar files to load
-effort[:min|less|default|more|max] set analysis effort level
-adjustExperimental lower priority of experimental Bug Patterns
-workHard ensure analysis effort is at least 'default'
-conserveSpace same as -effort:min (for backward compatibility)
-showPlugins show list of available detector plugins
-userPrefs <filename> user preferences file, e.g /path/to/project/.settings/edu.umd.cs.findbugs.core.prefs for Eclipse projects
Output options:
-timestampNow set timestamp of results to be current time
-quiet suppress error messages
-longBugCodes report long bug codes
-progress display progress in terminal window
-release <release name> set the release name of the analyzed application
-experimental report of any confidence level including experimental bug patterns
-low report warnings of any confidence level
-medium report only medium and high confidence warnings [default]
-high report only high confidence warnings
-maxRank <rank> only report issues with a bug rank at least as scary as that provided
-dontCombineWarnings Don't combine warnings that differ only in line number
-sortByClass sort warnings by class
-xml[:withMessages] XML output (optionally with messages)
-xdocs xdoc XML output to use with Apache Maven
-sarif SARIF 2.1.0 output
-html[:stylesheet] Generate HTML output (default stylesheet is default.xsl)
-emacs Use emacs reporting format
-relaxed Relaxed reporting mode (more false positives!)
-train[:outputDir] Save training data (experimental); output dir defaults to '.'
-useTraining[:inputDir] Use training data (experimental); input dir defaults to '.'
-redoAnalysis <filename> Redo analysis using configuration from previous analysis
-sourceInfo <filename> Specify source info file (line numbers for fields/classes)
-projectName <project name> Descriptive name of project
-reanalyze <filename> redo analysis in provided file
-output <filename> Save output in named file
-nested[:true|false] analyze nested jar/zip archives (default=true)
Output filtering options:
-bugCategories <cat1[,cat2...]> only report bugs in given categories
-onlyAnalyze <classes/packages> only analyze given classes and packages; end with .* to indicate classes in a package, .- to indicate a package prefix
-excludeBugs <baseline bugs> exclude bugs that are also reported in the baseline xml output
-exclude <filter file> exclude bugs matching given filter
-include <filter file> include only bugs matching given filter
-applySuppression Exclude any bugs that match suppression filter loaded from fbp file
Detector (visitor) configuration options:
-visitors <v1[,v2...]> run only named visitors
-omitVisitors <v1[,v2...]> omit named visitors
-chooseVisitors <+v1,-v2,...> selectively enable/disable detectors
-choosePlugins <+p1,-p2,...> selectively enable/disable plugins
-adjustPriority <v1=(raise|lower)[,...]> raise/lower priority of warnings for given visitor(s)
Project configuration options:
-auxclasspath <classpath> set aux classpath for analysis
-auxclasspathFromInput read aux classpath from standard input
-auxclasspathFromFile <filepath> read aux classpaths from a designated file
-sourcepath <source path> set source path for analyzed classes
-exitcode set exit code of process
-noClassOk output empty warning file if no classes are specified
-xargs get list of classfiles/jarfiles from standard input rather than command line
-analyzeFromFile <filepath> get the list of class/jar files from a designated file
-bugReporters <name,name2,-name3> bug reporter decorators to explicitly enable/disable
-printConfiguration print configuration and exit, without running analysis
-version print version, check for updates and exit, without running analysis
gui参数
General FindBugs options:
-project <project> analyze given project
-home <home directory> specify SpotBugs home directory
-pluginList <jar1[:jar2...]> specify list of plugin Jar files to load
-effort[:min|less|default|more|max] set analysis effort level
-adjustExperimental lower priority of experimental Bug Patterns
-workHard ensure analysis effort is at least 'default'
-conserveSpace same as -effort:min (for backward compatibility)
-f <font size> set font size
-clear clear saved GUI settings and exit
-priority <thread priority> set analysis thread priority
-loadBugs <saved analysis results> load bugs from saved analysis results
-d disable docking
--nodock disable docking
-look[:plastic|gtk|native] set UI look and feel
常用参数示例
# -javahome 指定运行spotbugs的java版本 【需要修改】
# -jvmArgs 可以通过改配置设置分析参数
# -maxHeap java虚拟机内存,单位M 【可以修改】
# -textui 命令行模式运行
# -auxclasspath 被分析项目依赖jar包路径 【需要修改】
# -sourcepath 分析对象的源文件目录 【需要修改】
# -sarif 输出sarif格式的报告 【可以修改】
# -dontCombineWarnings 不合并仅仅行号不同的问题
# 最后一行指定分析class的目录、jar包、clas文件、zip包 多个之间空格分开
./spotbugs-4.8.3/bin/spotbugs \
-javahome ./jdk1.8.0_202 \
-jvmArgs "-Duser.language=en" \
-maxHeap 3072 \
-textui \
-auxclasspath ./be-analyzed-depend \
-sourcepath ./source-code \
-sarif=./report.sarif.json \
-dontCombineWarnings \
./be-analyzed-class ./be-analyzed-jar
# 其他可选参数让分析更灵活
# -effort[:min|less|default|more|max] 分析工作量级别,min最快
# -pluginList <jar1[;jar2…]> 加载扩展插件
# -home <home directory> 指定spotbugs的安装目录
# 报告过滤
# -include filterFile.xml 报告结果过滤
# -exclude filterFile.xml 报告结果过滤
# -bugCategories cat1[,cat2…] 输出指定类别问题
# 指定部分文件分析
# -onlyAnalyze com.foobar.MyClass,com.foobar.mypkg.,!com.foobar.mypkg.ExcludedClass* 指定分析对象
# -analyzeFromFile filepath 在文件中配置被分析的对象
# 指定运行的分析器
# -visitors v1[,v2…] 运行指定的分析器
# -omitVisitors v1[,v2…] 禁用指定分析器
# -chooseVisitors +v1,-v2,… 开启或者禁用指定分析器
# -adjustPriority v1=(raise|lower)[,…] 调整分析器问题等级
# 指定运行的插件
# -choosePlugins +p1,-p2 开启禁用插件
# 开启调试
# -debug
# 文档链接
# 报告问题分类: https://spotbugs.readthedocs.io/en/latest/bugDescriptions.html#
# 分析器: https://spotbugs.readthedocs.io/en/latest/detectors.html#
# 分析参数: https://spotbugs.readthedocs.io/en/latest/analysisprops.html# 参数通过-jvmArgs配置
# 报告过滤文件(filterFile.xml)结果解析: https://spotbugs.readthedocs.io/en/latest/filter.html#
问题分类
https://spotbugs.readthedocs.io/en/latest/bugDescriptions.html#
分析器介绍
https://spotbugs.readthedocs.io/en/latest/detectors.html#
filterFile.xml例子
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter
xmlns="https://github.com/spotbugs/filter/3.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://github.com/spotbugs/filter/3.0.0 https://raw.githubusercontent.com/spotbugs/spotbugs/3.1.0/spotbugs/etc/findbugsfilter.xsd">
<Match>
<Class name="com.foobar.ClassNotToBeAnalyzed" />
</Match>
<Match>
<Class name="com.foobar.ClassWithSomeBugsMatched" />
<Bug code="DE,UrF,SIC" />
</Match>
<!-- Match all XYZ violations. -->
<Match>
<Bug code="XYZ" />
</Match>
<!-- Match all doublecheck violations in these methods of "AnotherClass". -->
<Match>
<Class name="com.foobar.AnotherClass" />
<Or>
<Method name="nonOverloadedMethod" />
<Method name="frob" params="int,java.lang.String" returns="void" />
<Method name="blat" params="" returns="boolean" />
</Or>
<Bug code="DC" />
</Match>
<!-- A method with a dead local store false positive (medium priority). -->
<Match>
<Class name="com.foobar.MyClass" />
<Method name="someMethod" />
<Bug pattern="DLS_DEAD_LOCAL_STORE" />
<Priority value="2" />
</Match>
<!-- All bugs in test classes, except for JUnit-specific bugs -->
<Match>
<Class name="~.*\.*Test" />
<Not>
<Bug code="IJU" />
</Not>
</Match>
</FindBugsFilter>
工具扩展:
GUI和工具集成
反编译工具
打开GUI界面(反编译工具):%SPOTBUGS_HOME%\lib\spotbugs.jar
分析工具GUI
打开分析界面:java -jar %SPOTBUGS_HOME%/lib/spotbugs.jar -gui
jdk19运行该工具报错,换成open jdk1.8运行成功。
新建分析项目: 文件>新建
分析目标:
可以直接选择zip, jar, ear, or war文件进行分析,可以选择包含class的目录,也可以两者同时选择。
辅助类:
另一个可选步骤是添加其他 Jar 文件或目录作为“辅助类路径位置”条目。 如果您正在分析的档案和目录引用了未包含在分析的档案/目录中且不在标准运行时类路径中的其他类,则应该执行此操作。 FindBugs 中的一些错误模式检测器利用类层次结构信息,因此如果 FindBugs 执行分析的整个类层次结构可用,您将获得更准确的结果。
源文件:
添加源目录,其中包含正在分析的 Java 包的源代码。 这将使 SpotBugs 能够突出显示包含可能错误的源代码。 添加的源目录应该是 Java 包层次结构的根。 例如,如果您的应用程序包含在 org.foobar.myapp 包中,则应将 org 目录的父目录添加到项目的源目录列表中。
分析结果界面: