Spring Boot 2.1.x の Web アプリを 2.2.x へバージョンアップする ( その9 )( SpotBugs を 3.1.11 → 4.0.0-beta4 へバージョンアップする )
概要
記事一覧はこちらです。
Spring Boot 2.1.x の Web アプリを 2.2.x へバージョンアップする ( その8 )( Error Prone を 2.3.3 → 2.3.4 へバージョンアップする ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- SpotBugs を 3.1.11 → 4.0.0-beta4 へバージョンアップします。
- https://mvnrepository.com/artifact/com.github.spotbugs/spotbugs を見ると安定版?(beta が付いていないもの)の最新版が 3.1.12(Mar, 2019)、その後 4.0.0 が beta で開発が進んでいて最新版が 4.0.0-beta4(Sep, 2019)でした。今回は 4.0.0-beta4 にバージョンアップします。
参照したサイト・書籍
- default.xsl declares it is a 2.0 stylesheet, but it appears to have issues with a 2.0 processor
https://github.com/spotbugs/spotbugs/issues/958
目次
手順
build.gradle を変更する
コメントアウトしていた SpotBugs の設定を元に戻した後、以下の点を変更します。
plugins { .......... id "com.github.spotbugs" version "3.0.0" .......... } .......... spotbugs { toolVersion = "4.0.0-beta4" ignoreFailures = true effort = "max" spotbugsTest.enabled = false } tasks.withType(com.github.spotbugs.SpotBugsTask) { reports { xml.enabled = false html.enabled = true } } .......... dependencies { .......... def spotbugsVersion = "4.0.0-beta4"
- plugins block の以下の点を変更します。
id "com.github.spotbugs" version "1.6.9"
→id "com.github.spotbugs" version "3.0.0"
- spotbugs block の以下の点を変更します。
toolVersion = "3.1.11"
→toolVersion = "4.0.0-beta4"
- dependencies block の以下の点を変更します。
def spotbugsVersion = "3.1.11"
→def spotbugsVersion = "4.0.0-beta4"
Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新した後、clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると "BUILD SUCCESSFUL" のメッセージは出力されますが2種類の警告も出力されました。
> Task :spotbugsMain SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. Warning at xsl:variable on line 348 column 57 of default.xsl: SXWN9001: A variable with no following sibling instructions has no effect Warning at xsl:variable on line 351 column 57 of default.xsl: SXWN9001: A variable with no following sibling instructions has no effect
警告の原因を取り除く(かもしれない)
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
ログに出力されている http://www.slf4j.org/codes.html#StaticLoggerBinder を見ると slf4j-nop.jar slf4j-simple.jar, slf4j-log4j12.jar, slf4j-jdk14.jar or logback-classic.jar のいずれかの jar ファイルが classpath に含まれていればこのメッセージは出力されなくなると書かれています。
が、build.gradle の dependencies block に以下のいずれかを追加しても SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
のメッセージは消えず、testJUnit4AndSpock タスクまで java.lang.IllegalArgumentException が発生してテストが多数失敗しました。compileOnly → implementation に変更しても結果は同じでした。
compileOnly("org.slf4j:slf4j-nop")
compileOnly("org.slf4j:slf4j-simple")
compileOnly("org.slf4j:slf4j-log4j12")
compileOnly("org.slf4j:slf4j-jdk14")
compileOnly("ch.qos.logback:logback-classic")
分からない。。。と思って Web で検索したところ、spotbugs/spotbugs-gradle-plugin の Issue に SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder" があり、まだ Open の状態でした。
動作には支障がないようなので、このメッセージは出したままにします。
Warning at xsl:variable on line 348 column 57 of default.xsl: SXWN9001: A variable with no following sibling instructions has no effect
default.xsl declares it is a 2.0 stylesheet, but it appears to have issues with a 2.0 processor に対応方法のサンプルが書かれているので、これを参考に変更します。
build.gradle を以下のように変更して、SpotBugs の HTML のレポートファイルが使用するスタイルシートを default.xsl → color.xsl に変更します。
configurations { .......... // for SpotBugs spotbugsStylesheets { transitive = false } } .......... spotbugs { toolVersion = "4.0.0-beta4" ignoreFailures = true effort = "max" spotbugsTest.enabled = false } tasks.withType(com.github.spotbugs.SpotBugsTask) { reports { xml.enabled = false html.enabled = true html.stylesheet = resources.text.fromArchiveEntry(configurations.spotbugsStylesheets, "color.xsl") } } .......... dependencies { .......... // for SpotBugs compileOnly("com.github.spotbugs:spotbugs:${spotbugsVersion}") compileOnly("net.jcip:jcip-annotations:1.0") compileOnly("com.github.spotbugs:spotbugs-annotations:${spotbugsVersion}") testImplementation("com.google.code.findbugs:jsr305:3.0.2") spotbugsStylesheets("com.github.spotbugs:spotbugs:${spotbugsVersion}") }
- configurations block の以下の点を変更します。
spotbugsStylesheets { transitive = false }
を追加します。
tasks.withType(com.github.spotbugs.SpotBugsTask) { ... }
の以下の点を変更します。html.stylesheet = resources.text.fromArchiveEntry(configurations.spotbugsStylesheets, "color.xsl")
を追加します。
- dependencies block の以下の点を変更します。
spotbugsStylesheets("com.github.spotbugs:spotbugs:${spotbugsVersion}")
を追加します。
Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新した後、clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると メッセージは消えて "BUILD SUCCESSFUL" のメッセージも出力されました。
com.github.spotbugs:spotbugs:4.0.0-beta4
の中を見ると、スタイルシートは default.xsl 以外に以下のものがあります。
各スタイルシートでどのようなレポートファイルが出力されるのかサンプルを作成してみます。SpotBugs の 検知可能なバグの詳細 を見て SpotBugs に検知されるバグを含んだソースを作成します。
src/main/java/ksbysample/webapp/lending/BugSample.java を新規作成し、以下の内容を記述します。NP: 戻り型が Boolean のメソッドが明示的に null を返している (NP_BOOLEAN_RETURN_NULL) の bug を含んだサンプルです。
package ksbysample.webapp.lending; public class BugSample { public Boolean func() { return null; } }
各スタイルシートの HTML のレポートファイルのサンプルを作成してみる
作成してみた感想としては、bug の数が少ないならば1ページにすべて表示できる color.xsl が使い勝手が良さそうで、数が出そうなら fancy.xsl、fancy-hist.xsl の方が便利でしょうか? summary.xsl は普段は使用しない気がします。
個人的には color.xsl が好みですね。
color.xsl
fancy.xsl
fancy-hist.xsl
plain.xsl
plain.xsl は以下のエラーが出て使えませんでした。
Warning at xsl:variable on line 277 column 56 of plain.xsl: SXWN9001: A variable with no following sibling instructions has no effect Warning at xsl:variable on line 280 column 59 of plain.xsl: SXWN9001: A variable with no following sibling instructions has no effect Error evaluating ((<head {(<title {text{"SpotBugs Report"}}/>, ...)}/>, ...)) on line 44 column 8 of plain.xsl: SEPM0009: Values of 'standalone' and 'omit-xml-declaration' conflict In template rule with match="/" on line 42 of plain.xsl The following errors occurred during analysis: Could not generate HTML output net.sf.saxon.trans.XPathException: Values of 'standalone' and 'omit-xml-declaration' conflict At net.sf.saxon.serialize.XMLEmitter.writeDeclaration(XMLEmitter.java:271) At net.sf.saxon.serialize.XMLEmitter.openDocument(XMLEmitter.java:188) At net.sf.saxon.serialize.XMLEmitter.characters(XMLEmitter.java:644) At net.sf.saxon.serialize.XMLIndenter.indent(XMLIndenter.java:327) At net.sf.saxon.serialize.XMLIndenter.startElement(XMLIndenter.java:115) At net.sf.saxon.event.ProxyReceiver.startElement(ProxyReceiver.java:132) At net.sf.saxon.event.SequenceNormalizer.startElement(SequenceNormalizer.java:88) At net.sf.saxon.event.NamespaceReducer.startElement(NamespaceReducer.java:75) At net.sf.saxon.event.ComplexContentOutputter.startContent(ComplexContentOutputter.java:640) At net.sf.saxon.event.ComplexContentOutputter.startElement(ComplexContentOutputter.java:271) At net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:345) At net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:299) At net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:735) At net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:132) At net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:352) At net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:299) At net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:352) At net.sf.saxon.trans.Mode.applyTemplates(Mode.java:532) At net.sf.saxon.trans.XsltController.applyTemplates(XsltController.java:747) At net.sf.saxon.s9api.AbstractXsltTransformer.applyTemplatesToSource(AbstractXsltTransformer.java:347) At net.sf.saxon.s9api.XsltTransformer.transform(XsltTransformer.java:349) At net.sf.saxon.jaxp.TransformerImpl.transform(TransformerImpl.java:71) At edu.umd.cs.findbugs.HTMLBugReporter.finish(HTMLBugReporter.java:73) At edu.umd.cs.findbugs.DelegatingBugReporter.finish(DelegatingBugReporter.java:89) At edu.umd.cs.findbugs.DelegatingBugReporter.finish(DelegatingBugReporter.java:89) At edu.umd.cs.findbugs.FindBugs2.analyzeApplication(FindBugs2.java:1165) At edu.umd.cs.findbugs.FindBugs2.execute(FindBugs2.java:309) At com.github.spotbugs.internal.spotbugs.SpotBugsExecutor.runSpotbugs(SpotBugsExecutor.java:23) At java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) At java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) At java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) At java.base/java.lang.reflect.Method.invoke(Method.java:566) At org.gradle.process.internal.worker.request.WorkerAction$1.call(WorkerAction.java:129) At org.gradle.process.internal.worker.child.WorkerLogEventListener.withWorkerLoggingProtocol(WorkerLogEventListener.java:41) At org.gradle.process.internal.worker.request.WorkerAction.run(WorkerAction.java:126) At org.gradle.process.internal.worker.request.WorkerAction.runThenStop(WorkerAction.java:105) At java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) At java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) At java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) At java.base/java.lang.reflect.Method.invoke(Method.java:566) At org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) At org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) At org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182) At org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164) At org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:412) At org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) At org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48) At java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) At java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) At org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56) At java.base/java.lang.Thread.run(Thread.java:834)
summary.xsl
このレポートは「Bugs By Package」の下にパッケージ毎の結果が出力されるので、かなり長いです。
履歴
2020/01/04
初版発行。