Gradle comes standard with plugins for using static analysis tools. Learn how to bring them into your Gradle project.
If you find something wrong, please let us know or request an edit. : bow:
"Software testing from zero knowledge [revised edition]" When I was reading the book, I suddenly found that my project was Cyclomatic Complexity. I want to measure complexity).
In Java, there is a plug-in in Eclipse, but I personally want to use Eclipse only for writing code, and I also think that the Gradle plug-in makes it easy to reproduce the environment, so Gradle I wondered if it could be used from, and found out that the PMD plug-in is provided as standard. There are quite a lot of commentary articles in Japanese for this plug-in, and if I proceeded with reference to it, I was able to measure without any problems.
This time, I will introduce how to use it easily, including plugins that use other static analysis tools.
It is said that the method of analyzing without executing the program is called so. In Java, let the tool parse the source code and bytecode. Automatically executed by the machine can help you find bugs and inconsistencies that are difficult for the human eye to find, prevent bugs that may be embedded in the future, or rewrite them into more readable code.
Product | Version |
---|---|
Java SE | 1.8.0_111 |
OS | Windows 10 |
Gradle | 3.2.1 |
Use the previously created RatPack sample code.
Folder hierarchy(tree /f)
src
├─main
│ ├─java
│ │ └─jp
│ │ └─toastkid
│ │ ├─libs
│ │ │ └─tinysegmenter
│ │ │ CharacterClassifier.java
│ │ │ ScoreMap.java
│ │ │ TinySegmenter.java
│ │ │
│ │ └─ratpack
│ │ │ Main.java
│ │ │
│ │ └─models
│ │ WordCloud.java
│ │
│ └─resources
│ │ .ratpack
│ │ wordcloud.html
│ │
│ └─public
│ ├─images
│ │ favicon.png
│ │ icon.png
│ │
│ ├─javascripts
│ │ │ jquery-1.6.4.min.js
│ │ │
│ │ ├─d3
│ │ │ d3.js
│ │ │ LICENSE(d3)
│ │ │
│ │ └─d3-cloud
│ │ d3.layout.cloud.js
│ │ index.js
│ │ LICENSE
│ │ package.json
│ │ README.md
│ │
│ └─stylesheets
│ main.css
│
└─test
└─java
└─jp
└─toastkid
└─ratpack
└─models
WordCloudTest.java
PMD It is a static analysis tool that points out problematic code from basic programming indicators.
You can use it just by specifying the addition of the plugin.
build.gradle
apply plugin: 'pmd'
$ gradle pmdmain
Please run the.
Run
$ gradle pmdMain
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:pmdMain
BUILD SUCCESSFUL
Total time: 2.938 secs
The report file is output to `` `build / reports / pmd``` in HTML and XML format.
Basic, which is used by default, has few check items, so let's add a little. In PMD, you can use the rules posted at the link below.
http://pmd.sourceforge.net/pmd-4.3.0/rules/index.html
Cyclomatic Complexity can be measured by CodeSize. Now let's add Braces and CodeSize. Note that the prefix `` `java-``` was required when specifying the rule.
build.gradle
pmd {
ruleSets = [
'java-braces',
'java-codesize',
]
}
$ gradle pmdmain
Please run the.
Run
$ gradle pmdMain
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:pmdMain FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':pmdMain'.
> 10 PMD rule violations were found. See the report at: file:///C:/Users/Toast%20kid/Documents/workspace/ratpack_word_cloud-master/build/reports/pmd/main.html
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 2.266 secs
The build failed forcibly because the number of indications was above a certain level.
project\src\main\java\jp\toastkid\libs\tinysegmenter\ScoreMap.java 1492 The constructor 'ScoreMap' has a Cyclomatic Complexity of 43.
It was pointed out that "ScoreMap.java constructor has 43 Cyclomatic Complexity". The lower this value is, the more concise the code is, with more than 20 being cautionary and more than 50 being quite complex. By default, CodeSize gives a Warning when it is 10 or more.
C = number of program routes-number of program branch points + 2
That's not always a good thing, but in that case you can add ignoreFailures = true
and the build will succeed.
build.gradle
pmd {
ignoreFailures = true
ruleSets = [
……
}
$ gradle pmdmain
Please run the.
Run
$ gradle pmdMain
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:pmdMain
10 PMD rule violations were found. See the report at: file:///C:/Users/Toast%20kid/Documents/workspace/ratpack_word_cloud-master/build/reports/pmd/main.html
BUILD SUCCESSFUL
Total time: 2.25 secs
-Perform static analysis with PMD in Gradle -Chapter 33 PMD Plugin
FindBugs It is a static analysis tool that points out the parts that are likely to be a hotbed of bugs from Java code.
Add to build.gradle.
build.gradle
apply plugin: 'findbugs'
$ gradle findbugsmain
Execute the analysis with the command.
Run
$ gradle findbugsMain
:compileJava
:processResources
:classes
:findbugsMain
Download https://repo1.maven.org/maven2/com/google/code/findbugs/findbugs/3.0.1/findbugs-3.0.1.pom
...(Omission)...
Download https://repo1.maven.org/maven2/org/ow2/asm/asm/5.0.2/asm-5.0.2.jar
:findbugsMain
FindBugs rule violations were found. See the report at: projet/build/reports/findbugs/main.xml
The analysis result is output in XML. I want to see it in HTML, but I couldn't find the option.
Sample
<BugInstance type="NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE" priority="2" rank="13" abbrev="NP" category="STYLE">
<Class classname="jp.toastkid.jfx.common.Style">
<SourceLine classname="jp.toastkid.jfx.common.Style" start="36" end="137" sourcefile="Style.java" sourcepath="jp/toastkid/jfx/common/Style.java"/>
</Class>
<Method classname="jp.toastkid.jfx.common.Style" name="findJarResourceDir" signature="()Ljava/util/List;" isStatic="true">
<SourceLine classname="jp.toastkid.jfx.common.Style" start="117" end="137" startBytecode="0" endBytecode="633" sourcefile="Style.java" sourcepath="jp/toastkid/jfx/common/Style.java"/>
</Method>
<LocalVariable name="?" register="-1" pc="219" role="LOCAL_VARIABLE_UNKNOWN"/>
<SourceLine classname="jp.toastkid.jfx.common.Style" start="133" end="133" startBytecode="219" endBytecode="219" sourcefile="Style.java" sourcepath="jp/toastkid/jfx/common/Style.java" role="SOURCE_LINE_INVOKED"/>
<SourceLine classname="jp.toastkid.jfx.common.Style" start="133" end="133" startBytecode="216" endBytecode="216" sourcefile="Style.java" sourcepath="jp/toastkid/jfx/common/Style.java" role="SOURCE_LINE_KNOWN_NULL"/>
<Property name="edu.umd.cs.findbugs.detect.NullDerefProperty.DEREFS_ARE_CLONED" value="true"/>
</BugInstance>
If you add ignoreFailures = true
to this plugin as well, the build will not be treated as a failure no matter how many warnings are issued.
build.gradle
findbugs {
ignoreFailures = true
Checkstyle Checkstyle is a tool for checking that Java source code complies with coding standards.
Add the following line to build.gradle.
build.gradle
apply plugin: 'checkstyle'
$ gradle check
Run the check with. If you want to check this plugin alone$ gradle checkstylemain
It is possible with.
Run(Failure)
$ gradle check
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:checkstyleMain
Download https://repo1.maven.org/maven2/com/puppycrawl/tools/checkstyle/5.9/checkstyle-5.9.pom
……(Omission)……
Download https://repo1.maven.org/maven2/com/google/guava/guava-jdk5/14.0.1/guava-jdk5-14.0.1.jar
:checkstyleMain FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':checkstyleMain'.
> Unable to create a Checker: unable to find project\config\checkstyle\checkstyle.xml
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 7.326 secs
If you run the check with nothing, it will fail as above. You need to prepare a checkstyle configuration file. So, get the configuration file that reproduces Sun's conventions from the following.
https://github.com/checkstyle/checkstyle
Add the config / checkstyle
folder to the root of your project and put the checkstyle.xml
there.
The command is the same as before.
Run
$ gradle check
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:checkstyleMain FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':checkstyleMain'.
> Unable to create a Checker: Property 'fileExtensions' in module Checker does not exist, please check the documentation
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 1.782 secs
It is said that fileExtensions does not exist.
Comment out the relevant part and try executing it.
Run
$ gradle check
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:checkstyleMain
[ant:checkstyle] project\src\main\java\jp\toastkid\libs\tinysegmenter\CharacterClassifier.java:0: Missing package-info.java file.
[ant:checkstyle] project\src\main\java\jp\toastkid\libs\tinysegmenter\CharacterClassifier.java:0:The file does not end with a new line.
……(Omitted because there are too many points)……
[ant:checkstyle] project\src\main\java\jp\toastkid\ratpack\models\WordCloud.java:79:58: 'str'To@Requires param tag.
:checkstyleMain FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':checkstyleMain'.
> Checkstyle rule violations were found. See the report at: project/build/reports/checkstyle/main.html
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 3.639 secs
Well, the code I prepared this time was really terrible ... Even with this plugin, if ignoreFailures
is false, the build will fail if a warning is issued. The report has been generated so let's take a look.
Report files are generated in html and xml under `` `build / reports / checkstyle / ```.
If you add ignoreFailures = true
to this plugin as well, the build will not be treated as a failure no matter how many warnings are issued.
build.gradle
checkstyle {
ignoreFailures = true
JaCoCo It is a plugin that outputs a test report. You can measure test coverage and see it visually. The name seems to be the acronym of "** Ja ** va ** Co ** de ** Co ** verage".
Add the JaCoCo plugin to build.gradle.
build.gradle
apply plugin: "jacoco"
The test build must be running. This time, run it with `$ gradle test jacocoTestReport`
.
Run
$ gradle test jacocoTestReport
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:test
:jacocoTestReport
BUILD SUCCESSFUL
Total time: 3.448 secs
By default, test reports are generated in HTML format at ``` build / reports / jacoco / test / html / index.html` ``.
packages
classes
methods
It becomes finer in the order of packages-> classes-> methods.
When you select a method name, a green background shows which part of the class was called from the test code, and a red background shows where it didn't pass. It's very easy to understand.
JDpend It seems to be a tool for static analysis on a package-by-package basis.
build.gradle
apply plugin: 'jdepend'
$ gradle jdependmain
Run with.
Run
$ gradle jdependMain
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jdependMain
Download https://repo1.maven.org/maven2/jdepend/jdepend/2.9.1/jdepend-2.9.1.pom
Download https://repo1.maven.org/maven2/org/apache/ant/ant-jdepend/1.9.6/ant-jdepend-1.9.6.pom
Download https://repo1.maven.org/maven2/org/apache/ant/ant-parent/1.9.6/ant-parent-1.9.6.pom
Download https://repo1.maven.org/maven2/jdepend/jdepend/2.9.1/jdepend-2.9.1.jar
Download https://repo1.maven.org/maven2/org/apache/ant/ant-jdepend/1.9.6/ant-jdepend-1.9.6.jar
[ant:jdependreport] ependMain
[ant:jdependreport] Unknown constant: 18
BUILD SUCCESSFUL
Total time: 3.719 secs
The report file is generated in XML format in build / reports / jdepend
.
If you add ignoreFailures = true
to this plugin as well, the build will not be treated as a failure no matter how many warnings are issued.
build.gradle
JDepend {
ignoreFailures = true
It has nothing to do with static analysis tools, but I learned that there seems to be such a plugin, so I will try it.
Add the plugin to build.gradle.
build.gradle
apply plugin: 'project-report'
$ gradle projectreport
Generate all reports with.
Run
$ gradle projectReport
:dependencyReport
:htmlDependencyReport
:propertyReport
:taskReport
:projectReport
BUILD SUCCESSFUL
Total time: 1.472 secs
build/reports/project/dependencies/root.It is output to html. JavaScript execution permission is required to display.
![projectReport.png](https://qiita-image-store.s3.amazonaws.com/0/102004/afbec792-774d-583f-ce7f-50f8aad62ea9.png)
It shows not only application compilation dependencies but also plugin dependencies. If the text format is good, it is generated in `` `build / reports / project / dependencies.txt` ``, so you should refer to that.
## reference
-[Chapter 41 Project Report Plugin](http://gradle.monochromeroad.com/docs/userguide/project_reports_plugin.html)
----
[License Gradle Plugin](https://github.com/hierynomus/license-gradle-plugin)
It's not a standard plugin, but I found it easy and useful to install, so I'll write about it. This is a plugin that traces the project license to the dependency and outputs it to the report.
Depending on the company, it may be necessary to check the license before using the OSS library or before releasing the deliverable, but if you have trouble following pom.xml one by one at such times, consider introducing this plugin You may try it.
## Introduction
[Output the license list of dependencies with gradle](http://blog.olivinecafe.info/post/105264504040/gradle%E3%81%A7dependencies%E3%81%AE%E3%83%A9%E3%82% A4% E3% 82% BB% E3% 83% B3% E3% 82% B9% E4% B8% 80% E8% A6% A7% E3% 82% 92% E5% 87% BA% E5% 8A% 9B% If you refer to E3% 81% 99% E3% 82% 8B), you can install it immediately.
Specifically, add the following to build.gradle and you're ready to go.
#### **`build.gradle`**
```groovy
apply plugin: "com.github.hierynomus.license"
......
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "gradle.plugin.nl.javadude.gradle.plugins:license-gradle-plugin:0.13.1"
}
}
$ gradle downloadlicenses
Please run the.
Run
$ gradle downloadLicenses
:downloadLicenses
BUILD SUCCESSFUL
Total time: 10.753 secs
build/reports/license/
Two types of html and xml are generated in the folder, for a total of four files.
file name | Description |
---|---|
license-dependency | Summary by license |
dependency-license | Summary by dependency unit |
license-dependency
dependency-license
`License-dependency``` is useful for checking for GPL-based licenses, and
`dependency-license``` is recommended if you need to look up individual licenses. ..
-[Output the license list of dependencies with gradle](http://blog.olivinecafe.info/post/105264504040/gradle%E3%81%A7dependencies%E3%81%AE%E3%83%A9%E3%82 % A4% E3% 82% BB% E3% 83% B3% E3% 82% B9% E4% B8% 80% E8% A6% A7% E3% 82% 92% E5% 87% BA% E5% 8A% 9B % E3% 81% 99% E3% 82% 8B)
I introduced how to use a static analysis tool that can be easily used from the Gradle plugin. It is important that these tools are automatically executed on a regular basis through CI, rather than being executed by typing commands each time.
Folder hierarchy(tree /f)
build
│
└─reports
├─jacoco
│ └─test
│ └─html
│ │ index.html
│ │ jacoco-sessions.html
│ │
│ ├─jacoco-resources
│ │ branchfc.gif
│ │ branchnc.gif
│ │ branchpc.gif
│ │ bundle.gif
│ │ class.gif
│ │ down.gif
│ │ greenbar.gif
│ │ group.gif
│ │ method.gif
│ │ package.gif
│ │ prettify.css
│ │ prettify.js
│ │ redbar.gif
│ │ report.css
│ │ report.gif
│ │ session.gif
│ │ sort.gif
│ │ sort.js
│ │ source.gif
│ │ up.gif
│ │
│ ├─jp.toastkid.libs.tinysegmenter
│ │ CharacterClassifier.html
│ │ CharacterClassifier.java.html
│ │ index.html
│ │ index.source.html
│ │ ScoreMap.html
│ │ ScoreMap.java.html
│ │ TinySegmenter.html
│ │ TinySegmenter.java.html
│ │
│ ├─jp.toastkid.ratpack
│ │ index.html
│ │ index.source.html
│ │ Main.html
│ │ Main.java.html
│ │
│ └─jp.toastkid.ratpack.models
│ index.html
│ index.source.html
│ WordCloud.html
│ WordCloud.java.html
│
├─license
│ dependency-license.html
│ dependency-license.xml
│ license-dependency.html
│ license-dependency.xml
│
├─pmd
│ main.html
│ main.xml
│
├─project
│ │ dependencies.txt
│ │ properties.txt
│ │ tasks.txt
│ │
│ └─dependencies
│ │ index.html
│ │ root.html
│ │ root.js
│ │
│ ├─css
│ │ base-style.css
│ │ style.css
│ │ tree.css
│ │
│ ├─images
│ │ d.gif
│ │ d.png
│ │ throbber.gif
│ │
│ └─js
│ jquery.jstree.js
│ jquery.min-1.11.0.js
│ script.js
│
└─tests
└─test
│ index.html
│
├─classes
│ jp.toastkid.ratpack.models.WordCloudTest.html
│
├─css
│ base-style.css
│ style.css
│
├─js
│ report.js
│
└─packages
jp.toastkid.ratpack.models.html
Recommended Posts