Integrating PVS-Studio Java into the Gradle build system
- Integrating the PVS-Studio plugin into Gradle
- How to run the analysis
- How to run the analysis without network access
- Configuration
- Updating PVS-Studio Java analyzer
PVS-Studio Java static analyzer consists of two main components: the analysis core and the plugins for integration the analyzer into build systems (Maven and Gradle) and IDEs (IntelliJ IDEA and Android Studio).
Plugins have the following features:
- run and configure the analyzer in a user-friendly interface;
- deploy the analyzer core in the system;
- collect and pass the project structure data (the set of source files and the classpath) to the analyzer core.
Integrating the PVS-Studio plugin into Gradle
To integrate the plugin using the Groovy DSL, add the following code to the build.gradle
script:
buildscript {
repositories {
mavenCentral()
maven {
url uri('https://wcdn.pvs-studio.com/java/pvsstudio-maven-repository/')
}
}
dependencies {
classpath 'com.pvsstudio:pvsstudio-gradle-plugin:latest.release'
}
}
apply plugin: com.pvsstudio.PvsStudioGradlePlugin
pvsstudio {
outputType = 'text'
outputFile = 'path/to/output.txt'
analysisMode = ['GA', 'OWASP']
}
To integrate the plugin with the Kotlin DSL, add the following code to the build.gradle.kts
script:
import com.pvsstudio.WarningGroup
buildscript {
repositories {
mavenCentral()
maven {
url = uri("https://wcdn.pvs-studio.com/java/pvsstudio-maven-repository/")
}
}
dependencies {
classpath("com.pvsstudio:pvsstudio-gradle-plugin:latest.release")
}
}
apply<com.pvsstudio.PvsStudioGradlePlugin>()
extensions.configure<com.pvsstudio.AnalyzerConfig>("pvsstudio") {
outputType = "text"
outputFile = ".pvs/output.txt"
analysisMode = setOf(WarningGroup.GA, WarningGroup.OWASP)
}
How to run the analysis
Before running the analysis, enter the PVS-Studio license. To learn how to do this, please consult the documentation.
To run the analysis, execute the following command:
./gradlew pvsAnalyze
Note. When analyzing a project, the plugin runs the Java analyzer core. The analyzer core uses the same Java language version as the JDK it is run with. The java
file from the JDK is used to run the Java analyzer core via the javaPath
setting. To change the Java language version used for the analysis, use the java
file from the JDK for that version to run the Java analyzer core.
How to run the analysis without network access
To run the plugin, you need to download its dependencies. If you work with the plugin on a system that without network access, create a local repository containing the plugin dependencies.
Use this command to download the dependencies and prepare them for offline use:
./gradlew build --refresh-dependencies
Run this command from the directory that contains the build.gradle
file (the project root directory). In this case, all the dependencies needed to build and analyze the project are saved in the default local repository folder:
- on Windows:
%userprofile%/.gradle/caches/modules-2/files-2.1
- on Linux or macOS:
~/.gradle/caches/modules-2/files-2.1
.
To download the dependencies, you need to have a network connection while running this command. Internet access is no longer required to continue working.
The system must be installed the same Java core version as the plugin. You can learn how to install the Java analyzer core in this documentation.
The analyzer is used the same way as in standard scenarios. To prevent Gradle from downloading dependencies, use the ‑‑offline
flag. This command runs the analysis in offline mode:
./gradlew pvsAnalyze –-offline
Configuration
Here is a list of analysis settings you can specify in the pvsstudio
section of the build.gradle
(for Groovy DSL) or build.gradle.kts
file (for Kotlin DSL):
outputType = "TYPE"
(Groovy or Kotlin) specifies the format of the analyzer report (text
,log
,json
,xml
,tasklist
,html
,fullhtml
, anderrorfile
). The default value isjson
;outputFile = "PATH"
(Groovy or Kotlin) specifies the path to the report file with analysis results. The file extension specified in this parameter does not affect the report format. The default value is$projectDir/PVS-Studio
with theformat extension from the outputType setting
. To generate a report in thefullhtml
format, specify the directory with thefullhtml
folder containing the analyzer report file (index.html
). The default value is$projectDir/fullhtml
.
Note. Instead of the outputFile
setting, it would be recommended to use the PlogConverter (Windows) and plog-converter (Linux and macOS) console utilities. They enable converting the analyzer report to more formats (for example, SARIF). The utilities provide additional features like filtering warnings from the report, converting paths in the report from absolute to relative (and vice versa), getting data on the differences between reports, etc.;
licensePath = "PATH"
(Groovy or Kotlin) specifies the path to the license file. Available file extensions are.xml
and.lic
. The default values are:- on Windows:
%APPDATA%/PVS-Studio/Settings.xml
- on macOS and Linux:
~/.config/PVS-Studio/PVS-Studio.lic
.
- on Windows:
threadsNum = NUMBER
(Groovy or Kotlin) sets the number of threads to which the analysis will be parallelized. You can set value for this setting for the whole system in theglobal.json
file. The default value isthe number of available processors
;sourceTreeRoot = "PATH"
(Groovy or Kotlin) specifies the root part of the path that the analyzer uses to generate relative paths in warnings. By default, PVS-Studio shows absolute file paths where the analyzer detects errors. This setting enables specifying the root path part (path to the directory). The analyzer automatically replaces it with a special marker. The file path is replaced if it begins with the specified root path. The report can be used with relative paths to view the analysis results in an environment with a different location of source files. For example, in different operating systems. The default value is none.analysisMode = ["GA", ....] ....]
(Groovy) /setOf(WarningMode.GA, ....)
(Kotlin) is the list of enabled warning groups. Available groups areGA
(general analysis diagnostic rules),OWASP
(OWASP ASVS compliant diagnostic rules).enabledWarnings
,disabledWarnings
, andadditionalWarnings
have a higher priority than this setting. If a diagnostic rule group is disabled (or enabled), you can use these settings to enable (or disable) individual diagnostic rules during the analysis. The default value isGA
;enabledWarnings = ["VXXXX", ....]
(Groovy) /setOf("VXXXX", ....)
(Kotlin) specifies the list of enabled diagnostic rules. During the analysis, the analyzer uses only the specified diagnostic rules in this list. If the value is none, all diagnostic rules are enabled unless a value is specified fordisabledWarnings
. The priority of theenabledWarnings
setting is lower thandisabledWarnings
andadditionalWarnings
but higher thananalysisMode
. The default value is none.disabledWarnings = ["VXXXX", ....]
(Groovy) /setOf("VXXX", ....)
(Kotlin) is the list of disabled diagnostic rules. During the analysis, the analyzer does not use the specified diagnostic rules in this list. If this setting is disabled, all diagnostic rules are enabled unlessanalyzeOnly
oranalyzeOnlyList
is set. The priority of thedisabledWarnings
setting is higher thanenabledWarnings
andanalysisMode
but lower thanadditionalWarnings
. The default value is none.additionalWarnings = ["VXXXX", ....]
(Groovy) /setOf("VXXXX", ....)
(Kotlin) is the list of diagnostic rules to be included in analysis, which are enabled by default. If a diagnostic rule is added to this list, its co-presence in theenabledWarnings
anddisabledWarnings
lists is ignored. In addition, you can enable the diagnostic rule even if the diagnostic rule group to which it belongs is disabled (i.e.analysisMode
does not contain this group). TheadditionalWarnings
setting has a higher priority than theenabledWarnings
,disabledWarnings
, andanalysisMode
settings. The default value is none.exclude = ["PATH", ....]
(Groovy) /setOf("PATH", ....)
(Kotlin) is the list of files and/or directories to be excluded from the analysis (absolute or relative paths are expanded relative to the project root directory). If this setting is disabled, all files are analyzed unless theanalyzeOnly
oranalyzeOnlyList
setting is enabled. The exclude setting has a higher priority than theanalyzeOnly
andanalyzeOnlyList
settings. The default value is none.analyzeOnly = ["PATH", ....]
(Groovy) /setOf("PATH", ....)
(Kotlin) is the list of files and/or directories to be analyzed (absolute or relative paths that are expanded relative to the project root directory). You can also write these paths to a file line-by-line and pass the path to that file to theanalyzeOnlyList
setting. If this setting is disabled, all files will be analyzed unless theexclude
oranalyzeOnlyList
setting is enabled. TheanalyzeOnly
setting has a lower priority than theexclude
setting. Files and/or directories passed in this setting are merged into a common list with files and/or directories from theanalyzeOnlyList
setting. The default value is none.analyzeOnlyList = "PATH"
(Groovy or Kotlin) is the path to the text file which contains the list of paths to files/directories to be analyzed (each entry must be on a separate line). Relative (will be expanded relative to the project root directory) and absolute paths are supported. If this setting is disabled, all files will be analyzed unless theexclude
oranalyzeOnly
setting is enabled. TheanalyzeOnlyList
setting has a lower priority than theexclude
setting. Files and/or directories read from the file specified in this setting are merged into a common list with files and/or directories from theanalyzeOnlyList
setting. The default value is none.suppressBase = "PATH"
(Groovy or Kotlin) is the path to the suppress file which contains suppressed warnings of the analyzer. Warnings from the suppress file will not be included in the report in any subsequent project checks. To add analyzer messages to a suppress file, use the interface of PVS-Studio plugin for IntelliJ IDEA and Android Studio. You can also use thepvsSuppress
task from thepvsstudio-gradle-plugin
plugin. The default value is$projectDir/.PVS-Studio/suppress_base.json
;failOnWarnings = BOOLEAN
(Groovy or Kotlin) terminates thepvsAnalyze
task with a failure if the analyzer has issued a warning. The flag enables monitoring analyzer warnings in the analyzer report. Such behavior can be useful when you integrate the analyzer into CI/CD. The default value isfalse
;incremental = BOOLEAN
(Groovy or Kotlin) enables incremental analysis. In this mode, the analyzer checks only modified files. The default value isfalse
;forceRebuild = BOOLEAN
(Groovy or Kotlin) forces rebuild the entire cached program metamodel. The metamodel contains data about the program structure and data types. Rebuilding the project metamodel can be necessary when the analyzer version is updated or if the project metamodel is corrupted. When this setting is used, the incremental analysis mode is disabled (theincremental
setting). The default value isfalse
;disableCache = BOOLEAN
(Groovy or Kotlin) disables caching of the program metamodel. When the cache is disabled, the project model is not cached and is rebuilt each time. This flag can be useful when identifying the causes of analyzer errors. Disabling project metamodel caching also disables the incremental analysis (theincremental
setting). The default value isfalse
;timeout = NUMBER
(Groovy or Kotlin) is the timeout for analyzing a file (in minutes). It enables you to increase or decrease the maximum amount of time taken to analyze one file. You can set value for this setting for the whole system in theglobal.json
file. The default value is10
;javaPath = "PATH"
(Groovy or Kotlin) specifies the path to the Java interpreter used to start the analyzer core. You can set value for this setting for the whole system in theglobal.json
file. The source code files are analyzed using the Java language version corresponding to the JDK build which path is set in this parameter. By default, PVS-Studio uses the path from thePATH
environment variable;jvmArguments = ["FLAG", ....]
(Groovy) /setOf("FLAG", ....)
(Kotlin) are the additional JVM flags used to execute the analyzer core. This flag enables configuring the JVM that runs the Java analyzer core. You can set value for this setting for the whole system in theglobal.json
file. The default value is["-Xss64m"]
;compatibility = BOOLEAN
(Groovy or Kotlin) enables the V6078 diagnostic rule that detects potential API compatibility issues between the selected Java SE versions. The V6078 diagnostic rules ensures that the JDK API you are using will not be modified or will not disappear in future JDK versions. The default value isfalse
;sourceJava = NUMBER
(Groovy or Kotlin) specifies the Java SE version that the application is developed on. The V6078 diagnostic rule uses this setting ifcompatibility
is enabled. The minimum value is8
. The maximum value is14
;targetJava = NUMBER
(Groovy or Kotlin) specifies the Java SE version to be checked for compatibility with the API used in the application (sourceJava
). The V6078 diagnostic rule uses this setting ifcompatibility
is enabled. The minimum value is8
. The maximum value is14
;excludePackages = ["PACK", ....]
(Groovy) /setOf("PACK", ....)
(Kotlin) excludes packages from the compatibility analysis (the V6078 diagnostic rule). The V6078 diagnostic rule uses this setting ifcompatibility
is enabled. The default value is none.securityRelatedIssues = BOOLEAN
(Groovy or Kotlin) highlights warnings related to potential security issues with additional mark up in theSAST
field in the analyzer output.logging = "LEVEL"
(Groovy or Kotlin) defines the logging level during analysis. When logging is enabled (any valid value other than "OFF" is set), log files for the current run are created in the .PVS-Studio/logs subdirectory relative to the project folder. These log files can help identify causes of analyzer malfunctions. Users may provide these files to help more quickly resolve issues related to incorrect analyzer behavior, such as unhandled exceptions during the analysis. The value should be one of the following strings: "OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "ALL". If an invalid value is set, logging is disabled ("OFF"). The default value is "OFF"—logging is disabled.
You can define the analyzer settings via the command line when running the analysis in the following format:
-Ppvsstudio.<nameSingleParam>=value
-Ppvsstudio.<nameMultipleParam>=value1;value2;value3
The example:
./gradlew pvsAnalyze -Ppvsstudio.outputType=text
-Ppvsstudio.outputFile=path/to/output.txt
-Ppvsstudio.disabledWarnings=V6001;V6002;V6003
Note. Parameters explicitly passed via the command line have the highest priority.
How to change the Java version to run the analyzer
By default, the analyzer starts the core with java
from the PATH
environment variable. If you need to run the analysis with some other version, you can set it manually, by specifying the path to java
from the JDK in the javaPath
analyzer setting. The version of this JDK (the Java language version) is used when analyzing the project's source code:
....
javaPath = "C:/Program Files/Java/jdk19.0.5/bin/java"
....
Updating PVS-Studio Java analyzer
By using latest.release
as the plugin version in the files build.gradle
or build.gradle.kts
,you always have the latest PVS-Studio version.
Using a proxy
When using a proxy, enter your login and password to correctly load the analyzer core, using the following arguments:
-Dhttp.proxyUser
and-Dhttp.proxyPassword
-Dhttps.proxyUser
and-Dhttps.proxyPassword
-Djava.net.socks.username
and-Djava.net.socks.password
-Dftp.proxyUser
and-Dftp.proxyPassword
.
You can use this command to run the analysis via the plugin for Gradle that uses a proxy:
./gradlew pvsAnalyze "-Dhttp.proxyUser=USER" "-Dhttp.proxyPassword=PASS"