### Execute SpotBugs Engine Setup Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsMojo.groovy.html This method sets up temporary files required for SpotBugs execution, including HTML, XML, and SARIF output files. It uses the `forceFileCreation` utility to ensure these files are ready. ```groovy private void executeSpotbugs(File outputFile) { log.debug('****** SpotBugsMojo executeSpotbugs *******') File htmlTempFile = new File("${outputDirectory}/spotbugs.html") if (htmlOutput) { forceFileCreation(htmlTempFile) } File xmlTempFile = new File("${project.build.directory}/spotbugsTemp.xml") forceFileCreation(xmlTempFile) File sarifTempFile = new File("${project.build.directory}/spotbugsTempSarif.json") if (sarifOutput) { ``` -------------------------------- ### Help Mojo Source: https://spotbugs.github.io/spotbugs-maven-plugin/apidocs/com/github/spotbugs/spotbugs_maven_plugin/HelpMojo.html The HelpMojo displays help information about the SpotBugs Maven Plugin. Users can invoke it via the Maven command line to get general help or detailed parameter information for specific goals. ```APIDOC ## Help Mojo ### Description Displays help information on the spotbugs-maven-plugin. This goal provides general usage instructions and can be extended to show detailed parameter information for specific goals. ### Method Mojo Goal ### Endpoint `mvn spotbugs:help` ### Parameters #### Query Parameters - **detail** (boolean) - Optional - If set to `true`, displays detailed parameter information for goals. - **goal** (string) - Optional - Specifies the goal for which to display detailed parameter information. If not provided, general help is shown. ### Request Example ```bash mvn spotbugs:help -Ddetail=true -Dgoal=spotbugs ``` ### Response #### Success Response Displays help text and parameter details in the console output. ``` -------------------------------- ### Get SpotBugs Command Line Arguments Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsMojo.groovy.html Prepares the list of command-line arguments for the SpotBugs execution. This method is intended to be called with temporary file paths for HTML, XML, SARIF, and auxiliary classpath. ```groovy private ArrayList getSpotbugsArgs(File htmlTempFile, File xmlTempFile, File sarifTempFile, File auxClasspathFile) { ``` -------------------------------- ### Clone SpotBugs Maven Plugin Repository (Anonymous Access) Source: https://spotbugs.github.io/spotbugs-maven-plugin/scm.html Use this command to check out the source code anonymously. Ensure Git is installed and configured. ```bash git clone --branch spotbugs-maven-plugin-4.9.8.5 ssh://git@github.com/spotbugs/spotbugs-maven-plugin.git ``` -------------------------------- ### Get SpotBugs Version Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/XDocsReporter.groovy.html Retrieves the current version string of the SpotBugs library. ```groovy protected static String getSpotBugsVersion() { return Version.VERSION_STRING } ``` -------------------------------- ### Launch SpotBugs GUI Source: https://spotbugs.github.io/spotbugs-maven-plugin/usage.html Launch the SpotBugs GUI for the current project, which will open the 'spotbugsXml.xml' file if it exists. This requires a minimal POM configuration. ```xml ... com.github.spotbugs spotbugs-maven-plugin 4.9.8.5 ... ``` -------------------------------- ### Get Report Output Path Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsAggregateMojo.groovy.html Returns the output path for the report, which is the plugin name. ```groovy String getOutputPath() { return SpotBugsInfo.PLUGIN_NAME } ``` -------------------------------- ### Configure Resource Manager and Output Directory Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsMojo.groovy.html Sets up the resource manager by adding search paths for project files and SpotBugs resources. It also defines the output directory for the build. ```groovy resourceManager.addSearchPath(FileResourceLoader.ID, session.getCurrentProject().getFile() .getParentFile().getAbsolutePath()) resourceManager.addSearchPath(SpotBugsInfo.URL, '') resourceManager.setOutputDirectory(new File(session.getCurrentProject().getBuild().directory)) ``` -------------------------------- ### Get Report Title Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotbugsReportGenerator.groovy.html Retrieves the report title from a resource bundle using a predefined key. ```Groovy protected String getReportTitle() { return bundle.getString(REPORT_TITLE_KEY) } ``` -------------------------------- ### Get Report Name Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsAggregateMojo.groovy.html Retrieves the name for the aggregate SpotBugs report, localized by the provided Locale. ```groovy String getName(Locale locale) { return getBundle(locale).getString(SpotBugsInfo.AGGREGATE_NAME_KEY) } ``` -------------------------------- ### main Method Source: https://spotbugs.github.io/spotbugs-maven-plugin/apidocs/com/github/spotbugs/StubOverrideFixer.html The main method serves as the entry point for the StubOverrideFixer application. It can throw an IOException. ```APIDOC ## main(String[] args) ### Description The main method. This is the entry point of the application. ### Method `public static void main(String[] args) throws IOException` ### Parameters * `args` (String[]) - The command-line arguments passed to the program. ### Throws * `IOException` - Signals that an I/O exception has occurred. ``` -------------------------------- ### Triggering Site Build Source: https://spotbugs.github.io/spotbugs-maven-plugin/examples/multi-module-config.html Command to execute to generate the project site, which includes SpotBugs reports. ```bash mvn site ``` -------------------------------- ### Get Report Description Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsAggregateMojo.groovy.html Retrieves the description for the aggregate SpotBugs report, localized by the provided Locale. ```groovy String getDescription(Locale locale) { return getBundle(locale).getString(SpotBugsInfo.AGGREGATE_DESCRIPTION_KEY) } ``` -------------------------------- ### Project Structure Overview Source: https://spotbugs.github.io/spotbugs-maven-plugin/examples/multi-module-config.html An overview of the initial project structure before organizing shared resources into a build-tools module. ```text whizbang |-- pom.xml |-- core | `-- pom.xml |-- gui | `-- pom.xml |-- jmx | `-- pom.xml `-- src ``` -------------------------------- ### Get Element Value Source: https://spotbugs.github.io/spotbugs-maven-plugin/xref/com/github/spotbugs/spotbugs_maven_plugin/HelpMojo.html Retrieves the text content of a single child element. Assumes the element exists and is unique. ```java private static String getValue( Node node, String elementName ) throws MojoExecutionException { return getSingleChild( node, elementName ).getTextContent(); } ``` -------------------------------- ### Get Resource Bundle Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsAggregateMojo.groovy.html Retrieves the ResourceBundle for localization based on the provided Locale. This is used for internationalizing messages and reports. ```Groovy ResourceBundle getBundle(Locale locale) { this.bundle = ResourceBundle.getBundle(SpotBugsInfo.BUNDLE_NAME, locale, SpotBugsAggregateMojo.class.getClassLoader()) if (log.isDebugEnabled()) { log.debug('Aggregate Mojo Locale is ' + this.bundle.getLocale().getLanguage()) } return bundle } ``` -------------------------------- ### Get Report Description Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsMojo.groovy.html Retrieves the plugin's description for the 'generated reports' overview page, localized by the provided locale. ```groovy /** * Returns the plugins description for the "generated reports" overview page. * * @param locale *                 the locale the report should be generated for * * @return description of the report * @see MavenReport#getDescription(Locale) */ @Override String getDescription(Locale locale) { return getBundle(locale).getString(SpotBugsInfo.DESCRIPTION_KEY) } ``` -------------------------------- ### Constructing SpotBugs Arguments Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsMojo.groovy.html This snippet demonstrates the logic for building the argument list for the SpotBugs executable based on various configuration parameters. It includes conditional logic for adding arguments related to user preferences, output files, and other analysis settings. ```groovy ResourceHelper resourceHelper = new ResourceHelper(log, spotbugsXmlOutputDirectory, resourceManager) List args = [] if (userPrefs) { if (log.isDebugEnabled()) { log.debug(" Adding User Preferences File -> ${userPrefs}") } args << '-userPrefs' args << resourceHelper.getResourceFile(userPrefs.trim()).getAbsolutePath() } if (htmlOutput) { log.debug(" Adding 'htmlOutput'") args << '-html=' + htmlTempFile.getAbsolutePath() } log.debug(" Adding 'xml:withMessages'") args << '-xml:withMessages=' + xmlTempFile.getAbsolutePath() if (sarifOutput) { log.debug(" Adding 'sarifOutput'") args << '-sarif=' + sarifTempFile.getAbsolutePath() } if (auxClasspathFile) { log.debug(" Adding 'auxclasspathFromFile'") args << '-auxclasspathFromFile' args << auxClasspathFile.getAbsolutePath() } log.debug(" Adding 'projectName'") args << '-projectName' args << project.name log.debug(" Adding 'effortParameter'") args << getEffortParameter() log.debug(" Adding 'thresholdParameter'") args << getThresholdParameter() if (debug) { log.debug(" Adding 'progress'") args << '-progress' } String spotbugsPlugins = getSpotbugsPlugins() if (spotbugsPlugins) { log.debug(" Adding 'pluginList'") args << '-pluginList' args << spotbugsPlugins } if (visitors) { log.debug(" Adding 'visitors'") args << '-visitors' args << visitors } if (omitVisitors) { log.debug(" Adding 'omitVisitors'") args << '-omitVisitors' args << omitVisitors } if (chooseVisitors) { log.debug(" Adding 'chooseVisitors'") args << '-chooseVisitors' args << chooseVisitors } if (relaxed) { log.debug(" Adding 'relaxed'") args << '-relaxed' } if (nested) { log.debug(" Adding 'nested:true'") args << '-nested:true' } else { log.debug(" Adding 'nested:false'") args << '-nested:false' } if (onlyAnalyze) { log.debug(" Adding 'onlyAnalyze'") args << '-onlyAnalyze' args << Arrays.stream(onlyAnalyze.split(SpotBugsInfo.COMMA)).map { String string -> string.startsWith('file:') ? Files.lines(resourceHelper.getResourceFile(string.substring(5)).toPath()) .collect(Collectors.joining(SpotBugsInfo.COMMA)) : string }.collect(Collectors.joining(',')) } if (includeFilterFile) { log.debug(' Adding Include Filter File') List includefilters = Arrays.asList(includeFilterFile.split(SpotBugsInfo.COMMA)) includefilters.each { String includefilter -> args << '-include' args << resourceHelper.getResourceFile(includefilter.trim()).getAbsolutePath() } } if (includeFilterFiles) { log.debug(' Adding Include Filter Files') includeFilterFiles.each { String includefilter -> args << '-include' args << resourceHelper.getResourceFile(includefilter.trim()).getAbsolutePath() } } if (excludeFilterFile) { log.debug(' Adding Exclude Filter File') List excludefilters = Arrays.asList(excludeFilterFile.split(SpotBugsInfo.COMMA)) ``` -------------------------------- ### Get Report Output Name Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsMojo.groovy.html Returns the report output file name, without the extension. This is used by AbstractMavenReport.execute() for creating the sink. ```groovy /** * Returns report output file name, without the extension. * * Called by AbstractMavenReport.execute() for creating the sink. * * @return name of the generated page * @see {@link MavenReport#getOutputName()} * */ ``` -------------------------------- ### Get Report Name Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsMojo.groovy.html Retrieves the plugin's name for the 'generated reports' overview page and menu, localized by the provided locale. ```groovy /** * Returns the plugins name for the "generated reports" overview page and the menu. * * @param locale *                 the locale the report should be generated for * * @return name of the report * @see MavenReport#getName(Locale) */ @Override String getName(Locale locale) { return getBundle(locale).getString(SpotBugsInfo.NAME_KEY) } ``` -------------------------------- ### Execute SpotBugs GUI Goal Source: https://spotbugs.github.io/spotbugs-maven-plugin/usage.html Execute the SpotBugs plugin with the 'gui' option to launch the graphical user interface. This is typically done after configuring the plugin in the POM. ```bash mvn spotbugs:gui ``` -------------------------------- ### Get Deprecated Output Name Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsAggregateMojo.groovy.html Returns the deprecated output name for the report. This method is marked as deprecated and should not be used in favor of getOutputPath(). ```groovy @Deprecated String getOutputName() { return SpotBugsInfo.PLUGIN_NAME } ``` -------------------------------- ### Build Tools Module Structure Source: https://spotbugs.github.io/spotbugs-maven-plugin/examples/multi-module-config.html This structure shows how to organize shared resources, such as SpotBugs configuration files, within a dedicated build-tools module. ```text whizbang |-- pom.xml |-- build-tools | |-- src | | `-- main | | `-- resources | | `-- whizbang | | |-- checkstyle.xml | | |-- lib-filter.xml | | `-- LICENSE.TXT | `-- pom.xml |`-- src `-- whiz-progs |-- pom.xml |-- core |-- gui `-- jmx ``` -------------------------------- ### Get Element Value from Node Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/com.github.spotbugs.spotbugs_maven_plugin/HelpMojo.java.html Retrieves the text content of a specified child element from a given Node. Throws MojoExecutionException if the element is not found. ```java private static String getValue( Node node, String elementName ) throws MojoExecutionException { return getSingleChild( node, elementName ).getTextContent(); } ``` -------------------------------- ### Configure Forked VM for Spotbugs Analysis Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsMojo.groovy.html Set the 'fork' parameter to true to enable forking a VM for Spotbugs analysis. This allows for custom timeouts and heap size configurations. ```groovy /** * Fork a VM for Spotbugs analysis. This will allow you to set timeouts and heap size. * * @since 2.3.2 */ @Parameter(defaultValue = 'true', property = 'spotbugs.fork') boolean fork ``` -------------------------------- ### Build Source File List Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SourceFileIndexer.groovy.html Initializes the complete list of source files by scanning resource and source directories of a Maven project. It uses a ReentrantLock for thread safety. ```groovy protected void buildListSourceFiles(MavenSession session) { lock.lock() try { // All source files to load allSourceFiles.clear() // Normalized base path String basePath = normalizePath(session.getExecutionRootDirectory()) // Get current project MavenProject project = session.getCurrentProject() // Resource for (Resource resource in project.getResources()) { scanDirectory(Path.of(resource.directory), basePath) } for (Resource resource in project.getTestResources()) { scanDirectory(Path.of(resource.directory), basePath) } // Source files for (String sourceRoot in project.getCompileSourceRoots()) { scanDirectory(Path.of(sourceRoot), basePath) } for (String sourceRoot in project.getTestCompileSourceRoots()) { scanDirectory(Path.of(sourceRoot), basePath) } // While not perfect, add the following paths will add basic support for Groovy, Kotlin, Scala and Webapp sources. scanDirectory(project.getBasedir().toPath().resolve('src/main/groovy'), basePath) scanDirectory(project.getBasedir().toPath().resolve('src/main/kotlin'), basePath) scanDirectory(project.getBasedir().toPath().resolve('src/main/scala'), basePath) scanDirectory(project.getBasedir().toPath().resolve('src/main/webapp'), basePath) scanDirectory(project.getBasedir().toPath().resolve('src/test/groovy'), basePath) scanDirectory(project.getBasedir().toPath().resolve('src/test/kotlin'), basePath) scanDirectory(project.getBasedir().toPath().resolve('src/test/scala'), basePath) scanDirectory(project.getBasedir().toPath().resolve('src/test/webapp'), basePath) } finally { lock.unlock() } } ``` -------------------------------- ### Get Report Output Directory Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsAggregateMojo.groovy.html Retrieves the absolute path of the report output directory. This is a standard getter method for accessing the report's destination. ```Groovy @Override protected String getOutputDirectory() { return outputDirectory.absolutePath } ``` -------------------------------- ### Specify Bug Detectors to Run Source: https://spotbugs.github.io/spotbugs-maven-plugin/usage.html Use the 'visitors' configuration option to specify a comma-separated list of bug detector class names to run. By default, all enabled detectors are run. Execute 'mvn site' to generate the report. ```xml ... com.github.spotbugs spotbugs-maven-plugin 4.9.8.5 FindDeadLocalStores,UnreadFields ... ``` ```bash mvn site ``` -------------------------------- ### Prepare Auxiliary Classpath Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsMojo.groovy.html This method prepares the auxiliary classpath by creating a temporary file. It excludes JAR files that contain classes in the 'java.*' package to prevent conflicts with JDK bootstrap classes. Debug logging is included for detailed information. ```groovy private File prepareAuxClasspath() { File auxClasspathFile = null if (auxClasspathList.size() > 0) { if (log.isDebugEnabled()) { log.debug('  Last AuxClasspath is -> ' + auxClasspathList[auxClasspathList.size() - 1]) } auxClasspathFile = new File(project.build.directory, 'spotbugsAuxClasspath.tmp') Files.createDirectories(auxClasspathFile.toPath().getParent()) if (log.isDebugEnabled()) { auxClasspathList.each { String auxClasspathElement -> log.debug('  Adding to AuxClasspath -> ' + auxClasspathElement) } } auxClasspathFile.text = auxClasspathList.join(SpotBugsInfo.EOL) + SpotBugsInfo.EOL } return auxClasspathFile } ``` -------------------------------- ### Get Threshold Parameter Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsMojo.groovy.html Determines the appropriate command-line parameter for the SpotBugs threshold based on the configured 'threshold' property. Defaults to '-medium' if no specific case matches. ```Groovy String thresholdParameter switch (threshold) { case 'High': thresholdParameter = '-high' break case 'Exp': thresholdParameter = '-experimental' break case 'Low': thresholdParameter = '-low' break case 'high': thresholdParameter = '-high' break default: thresholdParameter = '-medium' break } if (log.isDebugEnabled()) { log.debug("thresholdParameter is ${thresholdParameter}") } return thresholdParameter ``` -------------------------------- ### Get Single Child Node Source: https://spotbugs.github.io/spotbugs-maven-plugin/xref/com/github/spotbugs/spotbugs_maven_plugin/HelpMojo.html Retrieves a single child node by its element name. Throws an exception if the element is not found or if multiple elements with the same name exist. ```java private static Node getSingleChild( Node node, String elementName ) throws MojoExecutionException { List namedChild = findNamedChild( node, elementName ); if ( namedChild.isEmpty() ) { throw new MojoExecutionException( "Could not find " + elementName + " in plugin-help.xml" ); } if ( namedChild.size() > 1 ) { throw new MojoExecutionException( "Multiple " + elementName + " in plugin-help.xml" ); } return namedChild.get( 0 ); } ``` -------------------------------- ### Configure Plugin Documentation URLs Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsMojo.groovy.html Map SpotBugs plugin IDs to their documentation URL templates. The '{type}' placeholder is replaced with the bug type code. Provided entries override built-in defaults. ```groovy /** * Map of SpotBugs plugin IDs to their documentation URL templates. * The placeholder {@code {type}} in the template is replaced with the bug type code when * generating report links. *

* Built-in defaults are already provided for the following well-known plugins: *

    *
  • {@code com.mebigfatguy.fbcontrib} → * {@code https://fb-contrib.sourceforge.net/bugdescriptions.html#{type}}
  • *
  • {@code com.h3xstream.findsecbugs} → * {@code https://find-sec-bugs.github.io/bugs.htm#{type}}
  • *
* Entries provided here override the built-in defaults, allowing you to add support for * other SpotBugs addon plugins or customise the URLs for the ones above. * The plugin ID can be found in the {@code pluginid} attribute of the plugin's * {@code findbugs.xml} descriptor. *

* Example: *

{@code
 * 
 * 	https://example.com/bugs.html#{type}
 * 
 * }
* * @since 4.9.4.3 */ @Parameter Map pluginDocumentationUrls ``` -------------------------------- ### Get Effort Parameter String Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotBugsPluginsTrait.groovy.html Determines the effort parameter string based on the 'effort' variable. It maps 'Max' to 'max', 'Min' to 'min', and any other value to 'default'. ```Groovy String getEffortParameter() { String effortParameter = (effort == 'Max') ? 'max' : (effort == 'Min') ? 'min' : 'default' if (log.isDebugEnabled()) { log.debug("effort is ${effort}") log.debug("effortParameter is ${effortParameter}") } return "-effort:${effortParameter}" } ``` -------------------------------- ### Get Line Number Value Source: https://spotbugs.github.io/spotbugs-maven-plugin/jacoco/org.codehaus.mojo.spotbugs/SpotbugsReportGenerator.groovy.html Retrieves the line number information for a given line. Returns a default message if no source line is available. Handles single-line and multi-line ranges. ```groovy protected String valueForLine(GPathResult line) { String value if (line) { String startLine = line.@start.text() String endLine = line.@end.text() if (startLine == endLine) { if (startLine) { value = startLine } else { value = bundle.getString(NOLINE_KEY) } } else { value = startLine + '-' + endLine } } else { value = bundle.getString(NOLINE_KEY) } return value } ```