[JAVA] Utilisez des outils d'analyse statique dans votre projet Gradle

Aperçu

Gradle fournit un plug-in standard pour l'utilisation d'outils d'analyse statique. Apprenez à les intégrer dans votre projet Gradle.

Si vous trouvez quelque chose qui ne va pas, veuillez nous en informer ou demander une modification. : arc:

Contexte de l'article

"Test logiciel pour apprendre à partir de zéro connaissance [édition révisée]" Lorsque je lisais le livre, j'ai soudainement trouvé la complexité cyclomatique de mon projet. Je veux mesurer la complexité).

: question: Pourquoi Gradle

En Java, Eclipse a un plug-in, mais personnellement je souhaite utiliser Eclipse uniquement pour écrire du code, et je pense aussi que le plug-in Gradle facilite la reproduction de l'environnement, donc Gradle Je me suis demandé s'il pouvait être utilisé à partir de, et j'ai découvert que le plug-in PMD était fourni en standard. Il y a pas mal d'articles de commentaires en japonais pour ce plug-in, et si je procédais par référence à celui-ci, j'ai pu mesurer sans aucun problème.

: do_not_litter: Si vous avez un autre article existant, vous pouvez simplement inclure le lien et vous n'avez pas à écrire l'article.

Cette fois, je vais vous montrer comment l'utiliser facilement, y compris les plug-ins qui utilisent d'autres outils d'analyse statique.

Qu'est-ce que l'analyse statique?

On dit que la méthode d'analyse sans exécuter le programme est appelée ainsi. Dans le cas de Java, l'outil analyse le code source et le code d'octet. L'exécution automatique par la machine peut aider à trouver les défauts et les incohérences qui sont difficiles à trouver pour l'œil humain, à éviter de futurs bogues intégrés et à réécrire le code en un code hautement lisible.

Environnement d'exécution

Product Version
Java SE 1.8.0_111
OS Windows 10
Gradle 3.2.1

Projet cible

Utilisez l '[exemple de code RatPack] précédemment créé (https://github.com/toastkidjp/ratpack_word_cloud/tree/qiita2).

Hiérarchie des dossiers(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 C'est un outil d'analyse statique qui met en évidence le code problématique à partir des indicateurs de programmation de base.

introduction

Vous pouvez l'utiliser simplement en spécifiant l'ajout d'un plug.

build.gradle


apply plugin: 'pmd'

Courir

$ gradle pmdmainVeuillez exécuter le.

Courir


$ gradle pmdMain

:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:pmdMain

BUILD SUCCESSFUL

Total time: 2.938 secs

Le fichier de rapport est sorti au format HTML et XML vers build / reports / pmd```.

pmd1.png

règle ajoutée

Basic, qui est utilisé par défaut, a peu d'éléments de contrôle, ajoutons donc un peu. Dans PMD, vous pouvez utiliser les règles publiées sur le lien ci-dessous.

http://pmd.sourceforge.net/pmd-4.3.0/rules/index.html

La complexité cyclomatique peut être mesurée par CodeSize. Ajoutons des accolades et CodeSize cette fois. Notez que le préfixe `` java-'' était requis lors de la spécification de la règle.

build.gradle


pmd {
  ruleSets = [
    'java-braces',
    'java-codesize',
  ]
}

Courir

$ gradle pmdmainVeuillez exécuter le.

Courir


$ 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

La construction a échoué de force car le nombre d'indications était supérieur à un certain niveau.

Points à souligner

pmd2.png

project\src\main\java\jp\toastkid\libs\tinysegmenter\ScoreMap.java 	1492 	The constructor 'ScoreMap' has a Cyclomatic Complexity of 43.

Il a été souligné que "les constructeurs ScoreMap.java ont 43 Complexités Cyclomatiques". Plus cette valeur est basse, plus le code est concis, plus de 20 étant un avertissement et plus de 50 étant assez complexe. Par défaut, CodeSize donne un avertissement lorsqu'il est égal ou supérieur à 10.

Formule de complexité cyclomatique

C = nombre de routes de programme-nombre de points de branche de programme + 2

: avertissement: ne considérez pas la compilation comme un échec même s'il y a trop d'indications

Ce n'est pas toujours une bonne chose, mais dans ce cas, vous pouvez ajouter ignoreFailures = true et la compilation réussira.

Ajouté à build.gradle

build.gradle


pmd {
  ignoreFailures = true
  ruleSets = [
……
}

Courir

$ gradle pmdmainVeuillez exécuter le.

Courir


$ 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

référence


FindBugs C'est un outil d'analyse statique qui signale les bogues potentiels du code Java.

introduction

Ajouter à build.gradle.

build.gradle


apply plugin: 'findbugs'

Courir

$ gradle findbugsmainExécutez l'analyse avec la commande.

Courir


$ 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

rapport

Le résultat de l'analyse est sorti en XML. Je veux le voir en HTML, mais je n'ai pas trouvé l'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>

: avertissement: ne considérez pas la compilation comme un échec même s'il y a trop d'indications

Si vous ajoutez ignoreFailures = true à ce plug-in, la compilation ne sera pas traitée comme un échec quel que soit le nombre d'avertissements émis.

build.gradle


findbugs {
  ignoreFailures = true

référence


Checkstyle Checkstyle est un outil permettant de vérifier que le code source Java est conforme aux normes de codage.

introduction

Ajoutez la ligne suivante à build.gradle.

build.gradle


apply plugin: 'checkstyle'

: no_entry: Exécuter (échec)

$ gradle checkExécutez la vérification avec. Si vous souhaitez vérifier ce plug-in seul$ gradle checkstylemainC'est possible avec.

Courir(Échec)


$ 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

Ajouter un fichier de configuration

Si vous exécutez la vérification sans rien, elle échouera comme ci-dessus. Vous devez préparer un fichier de paramètres de contrôle. Alors, récupérez le fichier de configuration qui reproduit les règles de Sun à partir de ce qui suit.

https://github.com/checkstyle/checkstyle

Ajoutez le dossier config / checkstyle '' à la racine de votre projet et placez-y le checkstyle.xml ''.

: no_entry: réexécution (échec)

La commande est la même que précédemment.

Courir


$ 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

On dit que fileExtensions n'existe pas.

Commentez et exécutez

Commentez la partie pertinente et essayez de l'exécuter.

Courir


$ 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:Le fichier ne se termine pas par une nouvelle ligne.

……(Omis car il y a trop de points)……

[ant:checkstyle] project\src\main\java\jp\toastkid\ratpack\models\WordCloud.java:79:58: 'str'À@Nécessite une balise param.
: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

Eh bien, le code que j'ai préparé cette fois était vraiment terrible ... Même avec ce plug-in, si ignoreFailures est faux, la compilation échouera si un avertissement est émis. Le rapport a été généré alors jetons un œil.

rapport

Les fichiers de rapport sont générés en html et xml sous `` build / reports / checkstyle / ''.

cs.png

: avertissement: ne considérez pas la compilation comme un échec même s'il y a trop d'indications

Si vous ajoutez ignoreFailures = true à ce plug-in, la compilation ne sera pas traitée comme un échec quel que soit le nombre d'avertissements émis.

build.gradle


checkstyle {
  ignoreFailures = true

référence


JaCoCo Un plug-in qui génère des rapports de test. Vous pouvez mesurer et vous référer visuellement à la couverture de test. Le nom semble être l'acronyme de "** Ja ** va ** Co ** de ** Co ** verage".

introduction

Ajoutez le plug-in JaCoCo à build.gradle.

build.gradle


apply plugin: "jacoco"

Courir

La version de test doit être en cours d'exécution. Cette fois, lancez-le avec $ gradle test jacocoTestReport` ``.

Courir


$ 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

rapport

Par défaut, les rapports de test sont générés au format HTML dans build / reports / jacoco / test / html / index.html` ``.

packages jacoco.png

classes jacoco2.png

methods jacoco3.png

Il devient plus fin dans l'ordre des packages-> classes-> méthodes.

Détails

jacoco4.png

Lorsque vous sélectionnez un nom de méthode, un arrière-plan vert indique quelle partie de la classe a été appelée à partir du code de test, et un arrière-plan rouge indique où elle n'a pas réussi. C'est très facile à comprendre.

référence


JDpend Cela semble être un outil d'analyse statique paquet par paquet.

introduction

build.gradle


apply plugin: 'jdepend'

Courir

$ gradle jdependmainCourir avec.

Courir


$ 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

rapport

Les fichiers de rapport sont générés au format XML dans build / reports / jdepend```.

Ne considérez pas la construction comme un échec même s'il y a trop d'indications

Si vous ajoutez ignoreFailures = true à ce plug-in, la compilation ne sera pas traitée comme un échec quel que soit le nombre d'avertissements émis.

build.gradle


JDepend {
  ignoreFailures = true

référence


Plug-in de rapport de projet

Cela n'a rien à voir avec les outils d'analyse statique, mais j'ai appris qu'il semble y avoir un tel plug-in, alors je vais l'essayer.

introduction

Ajoutez le plug-in à build.gradle.

build.gradle


apply plugin: 'project-report'

Courir

$ gradle projectreportGénérez tous les rapports avec.

Courir


$ gradle projectReport

:dependencyReport
:htmlDependencyReport
:propertyReport
:taskReport
:projectReport

BUILD SUCCESSFUL

Total time: 1.472 secs

rapport

build/reports/project/dependencies/root.Il est sorti au format HTML. Pour l'afficher, vous avez besoin d'une autorisation pour exécuter JavaScript.



 ![projectReport.png](https://qiita-image-store.s3.amazonaws.com/0/102004/afbec792-774d-583f-ce7f-50f8aad62ea9.png)


 Il montre non seulement les dépendances de compilation d'application mais aussi les dépendances de plugins. Si le format de texte est bon, il est généré dans `` `` build / reports / project / dependencies.txt` '', vous devriez donc vous y référer.

## référence
 - [Chapitre 41 Plugin de rapport de projet](http://gradle.monochromeroad.com/docs/userguide/project_reports_plugin.html)

----
 [License Gradle Plugin](https://github.com/hierynomus/license-gradle-plugin)
 Ce n'est pas un plug-in standard, mais je l'ai trouvé facile et utile à installer, je vais donc en parler. Il s'agit d'un plug-in qui trace la licence du projet vers la dépendance et la renvoie dans le rapport.
 Selon l'entreprise, il peut être nécessaire de vérifier la licence avant d'utiliser la bibliothèque OSS ou avant de publier le livrable, mais s'il est difficile de suivre pom.xml un par un à de tels moments, envisagez d'introduire ce plug-in. Vous pouvez l'essayer.

## introduction
 [Sortie de la liste des dépendances de licence avec 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% Si vous vous référez à E3% 81% 99% E3% 82% 8B), vous pouvez l'installer immédiatement.

 Plus précisément, ajoutez ce qui suit à build.gradle et vous êtes prêt à partir.


#### **`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"
  }
}

Courir

$ gradle downloadlicensesVeuillez exécuter le.

Courir


$ gradle downloadLicenses

:downloadLicenses

BUILD SUCCESSFUL

Total time: 10.753 secs

rapport

build/reports/license/Deux types de html et xml sont générés dans le dossier, pour un total de quatre fichiers.

nom de fichier La description
license-dependency Résumé par licence
dependency-license Récapitulatif par unité de dépendance

license-dependency license2.png

dependency-license license1.png

License-dependency '' est utile pour vérifier les licences basées sur la GPL, et dependency-license``` est recommandé si vous avez besoin de rechercher des licences individuelles. ..

référence


Résumé

J'ai présenté comment utiliser un outil d'analyse statique qui peut être facilement utilisé à partir du plug-in Gradle. Il est important que ces outils soient automatiquement exécutés sur une base régulière via CI, plutôt que d'être exécutés en tapant des commandes à chaque fois.

échantillon

Hiérarchie des dossiers du rapport généré cette fois

Hiérarchie des dossiers(tree&nbsp;/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

Utilisez des outils d'analyse statique dans votre projet Gradle
Analyse de code statique par Checkstyle avec Java + Gradle
Exécuter l'analyse statique Infer dans l'environnement Windows
Exécuter des tests de projet modulaire dans Gradle (JUnit5 + TestFX)
Conseils Java - Créez un projet Spring Boot avec Gradle
Ajouter un projet dans n'importe quel dossier avec Gradle
Afficher la tâche Gradle dans le projet Spring Boot
Ajoutez un fichier jar externe dans un projet IntelliJ.