pmd/pmd_languages_java.html

2297 lines
63 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Java-specific features and guidance">
<meta name="keywords" content="languagesPmdCapableLanguageCpdCapableLanguage, ">
<title>Java support | PMD Source Code Analyzer</title>
<link rel="stylesheet" type="text/css" href="assets/fontawesome-free-5.15.4-web/css/all.min.css">
<link rel="stylesheet" type="text/css" href="assets/bootstrap-4.5.2-dist/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/syntax.css">
<link rel="stylesheet" type="text/css" href="css/modern-business.css">
<link rel="stylesheet" type="text/css" href="css/customstyles.css">
<link rel="stylesheet" type="text/css" href="css/theme-green.css">
<link rel="stylesheet" type="text/css" href="css/pmd-customstyles.css">
<link rel="shortcut icon" href="images/logo/favicon.ico" type="image/x-icon">
<link rel="icon" href="images/logo/favicon.ico" type="image/x-icon">
<link rel="alternate" type="application/rss+xml" title="" href="feed.xml">
</head>
<body>
<!-- Content is offset by the height of the topnav bar. -->
<!-- There's already a padding-top rule in modern-business.css, but it apparently doesn't work on Firefox 60 and Chrome 67 -->
<div id="topbar-content-offset">
<!-- Navigation -->
<nav class="navbar navbar-expand-lg fixed-top navbar-dark">
<div class="container topnavlinks">
<a class="navbar-brand fas fa-home fa-lg" href="index.html">&nbsp;<span class="projectTitle"> PMD Source Code Analyzer Project</span></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto mt-2 mt-lg-0"></ul>
<ul class="navbar-nav">
<!-- toggle sidebar button -->
<li class="nav-item"><a id="tg-sb-link" class="nav-link" href="#"><i id="tg-sb-icon" class="fas fa-toggle-on"></i> Nav</a></li>
<!-- entries without drop-downs appear here -->
<li class="nav-item"><a class="nav-link" href="https://github.com/pmd/pmd/releases/latest" target="_blank">Download</a></li>
<li class="nav-item"><a class="nav-link" href="https://github.com/pmd/pmd" target="_blank">Fork us on github</a></li>
<!-- entries with drop-downs appear here -->
<!-- conditional logic to control which topnav appears for the audience defined in the configuration file.-->
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="search..." id="search-input">
<ul id="results-container"></ul>
</form>
</div>
</div>
</nav>
<!-- Page Content -->
<div class="container-toc-wrapper">
<div class="container">
<div class="col-lg-12">&nbsp;</div>
<!-- Content Row -->
<div class="row">
<!-- Sidebar Column -->
<div class="col-md-3" id="tg-sb-sidebar">
<ul id="mysidebar" class="nav">
<li class="sidebarTitle">PMD 7.8.0-SNAPSHOT</li>
<div class="sidebarTitleDate">Release date: 29-November-2024</div>
<li>
<a href="#">About</a>
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="pmd_release_notes.html">Release notes</a></li>
<li><a href="pmd_release_notes_pmd7.html">Release notes (PMD 7)</a></li>
<li><a href="pmd_about_help.html">Getting help</a></li>
<li><a href="pmd_about_release_policies.html">Release policies</a></li>
<li><a href="pmd_about_support_lifecycle.html">Support lifecycle</a></li>
</ul>
</li>
<li>
<a href="#">User Documentation</a>
<ul>
<li><a href="pmd_userdocs_migrating_to_pmd7.html">Migration Guide for PMD 7</a></li>
<li><a href="pmd_userdocs_installation.html">Installation and basic CLI usage</a></li>
<li><a href="pmd_userdocs_making_rulesets.html">Making rulesets</a></li>
<li><a href="pmd_userdocs_configuring_rules.html">Configuring rules</a></li>
<li><a href="pmd_userdocs_best_practices.html">Best practices</a></li>
<li><a href="pmd_userdocs_suppressing_warnings.html">Suppressing warnings</a></li>
<li><a href="pmd_userdocs_incremental_analysis.html">Incremental analysis</a></li>
<li><a href="pmd_userdocs_cli_reference.html">PMD CLI reference</a></li>
<li><a href="pmd_userdocs_report_formats.html">PMD Report formats</a></li>
<li><a href="pmd_userdocs_3rdpartyrulesets.html">3rd party rulesets</a></li>
<li class="subfolders">
<a href="#">CPD reference</a>
<ul>
<li><a href="pmd_userdocs_cpd.html">Copy-paste detection</a></li>
<li><a href="pmd_userdocs_cpd_report_formats.html">CPD Report formats</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Extending PMD</a>
<ul>
<li><a href="pmd_userdocs_extending_writing_rules_intro.html">Introduction to writing rules</a></li>
<li><a href="pmd_userdocs_extending_your_first_rule.html">Your first rule</a></li>
<li><a href="pmd_userdocs_extending_writing_xpath_rules.html">XPath rules</a></li>
<li><a href="pmd_userdocs_extending_writing_java_rules.html">Java rules</a></li>
<li><a href="pmd_userdocs_extending_designer_reference.html">Rule designer reference</a></li>
<li><a href="pmd_userdocs_extending_defining_properties.html">Defining rule properties</a></li>
<li><a href="pmd_userdocs_extending_rule_guidelines.html">Rule guidelines</a></li>
<li><a href="pmd_userdocs_extending_testing.html">Testing your rules</a></li>
<li><a href="pmd_userdocs_extending_ast_dump.html">Creating (XML) dump of the AST</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Tools / Integrations</a>
<ul>
<li><a href="pmd_userdocs_tools_maven.html">Maven PMD Plugin</a></li>
<li><a href="pmd_userdocs_tools_gradle.html">Gradle</a></li>
<li><a href="pmd_userdocs_tools_ant.html">Ant</a></li>
<li><a href="pmd_userdocs_tools_java_api.html">PMD Java API</a></li>
<li><a href="pmd_userdocs_tools_bld.html">bld PMD Extension</a></li>
<li><a href="pmd_userdocs_tools_ci.html">CI integrations</a></li>
<li><a href="pmd_userdocs_tools.html">Other Tools / Integrations</a></li>
</ul>
</li>
</ul>
</li>
<li>
<a href="#">Rule Reference</a>
<ul>
<li class="subfolders">
<a href="#">Apex Rules</a>
<ul>
<li><a href="pmd_rules_apex.html">Index</a></li>
<li><a href="pmd_rules_apex_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_apex_codestyle.html">Code Style</a></li>
<li><a href="pmd_rules_apex_design.html">Design</a></li>
<li><a href="pmd_rules_apex_documentation.html">Documentation</a></li>
<li><a href="pmd_rules_apex_errorprone.html">Error Prone</a></li>
<li><a href="pmd_rules_apex_performance.html">Performance</a></li>
<li><a href="pmd_rules_apex_security.html">Security</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">HTML Rules</a>
<ul>
<li><a href="pmd_rules_html.html">Index</a></li>
<li><a href="pmd_rules_html_bestpractices.html">Best Practices</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Java Rules</a>
<ul>
<li><a href="pmd_rules_java.html">Index</a></li>
<li><a href="pmd_rules_java_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_java_codestyle.html">Code Style</a></li>
<li><a href="pmd_rules_java_design.html">Design</a></li>
<li><a href="pmd_rules_java_documentation.html">Documentation</a></li>
<li><a href="pmd_rules_java_errorprone.html">Error Prone</a></li>
<li><a href="pmd_rules_java_multithreading.html">Multithreading</a></li>
<li><a href="pmd_rules_java_performance.html">Performance</a></li>
<li><a href="pmd_rules_java_security.html">Security</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Java Server Pages Rules</a>
<ul>
<li><a href="pmd_rules_jsp.html">Index</a></li>
<li><a href="pmd_rules_jsp_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_jsp_codestyle.html">Code Style</a></li>
<li><a href="pmd_rules_jsp_design.html">Design</a></li>
<li><a href="pmd_rules_jsp_errorprone.html">Error Prone</a></li>
<li><a href="pmd_rules_jsp_security.html">Security</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">JavaScript Rules</a>
<ul>
<li><a href="pmd_rules_ecmascript.html">Index</a></li>
<li><a href="pmd_rules_ecmascript_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_ecmascript_codestyle.html">Code Style</a></li>
<li><a href="pmd_rules_ecmascript_errorprone.html">Error Prone</a></li>
<li><a href="pmd_rules_ecmascript_performance.html">Performance</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Kotlin Rules</a>
<ul>
<li><a href="pmd_rules_kotlin.html">Index</a></li>
<li><a href="pmd_rules_kotlin_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_kotlin_errorprone.html">Error Prone</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Maven POM Rules</a>
<ul>
<li><a href="pmd_rules_pom.html">Index</a></li>
<li><a href="pmd_rules_pom_errorprone.html">Error Prone</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Modelica Rules</a>
<ul>
<li><a href="pmd_rules_modelica.html">Index</a></li>
<li><a href="pmd_rules_modelica_bestpractices.html">Best Practices</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">PLSQL Rules</a>
<ul>
<li><a href="pmd_rules_plsql.html">Index</a></li>
<li><a href="pmd_rules_plsql_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_plsql_codestyle.html">Code Style</a></li>
<li><a href="pmd_rules_plsql_design.html">Design</a></li>
<li><a href="pmd_rules_plsql_errorprone.html">Error Prone</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Salesforce Visualforce Rules</a>
<ul>
<li><a href="pmd_rules_visualforce.html">Index</a></li>
<li><a href="pmd_rules_visualforce_security.html">Security</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Scala Rules</a>
<ul>
<li><a href="pmd_rules_scala.html">Index</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Swift Rules</a>
<ul>
<li><a href="pmd_rules_swift.html">Index</a></li>
<li><a href="pmd_rules_swift_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_swift_errorprone.html">Error Prone</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Velocity Template Language (VTL) Rules</a>
<ul>
<li><a href="pmd_rules_velocity.html">Index</a></li>
<li><a href="pmd_rules_velocity_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_velocity_design.html">Design</a></li>
<li><a href="pmd_rules_velocity_errorprone.html">Error Prone</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">WSDL Rules</a>
<ul>
<li><a href="pmd_rules_wsdl.html">Index</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">XML Rules</a>
<ul>
<li><a href="pmd_rules_xml.html">Index</a></li>
<li><a href="pmd_rules_xml_bestpractices.html">Best Practices</a></li>
<li><a href="pmd_rules_xml_errorprone.html">Error Prone</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">XSL Rules</a>
<ul>
<li><a href="pmd_rules_xsl.html">Index</a></li>
<li><a href="pmd_rules_xsl_codestyle.html">Code Style</a></li>
<li><a href="pmd_rules_xsl_performance.html">Performance</a></li>
</ul>
</li>
</ul>
</li>
<li>
<a href="#">Language-Specific Documentation</a>
<ul>
<li><a href="pmd_languages_index.html">Overview</a></li>
<li><a href="pmd_languages_configuration.html">Language configuration</a></li>
<li><a href="pmd_languages_apex.html">Apex</a></li>
<li><a href="pmd_languages_cpp.html">C/C++</a></li>
<li><a href="pmd_languages_cs.html">C#</a></li>
<li><a href="pmd_languages_coco.html">Coco</a></li>
<li><a href="pmd_languages_dart.html">Dart</a></li>
<li><a href="pmd_languages_fortran.html">Fortran</a></li>
<li><a href="pmd_languages_gherkin.html">Gherkin</a></li>
<li><a href="pmd_languages_go.html">Go</a></li>
<li><a href="pmd_languages_html.html">HTML</a></li>
<li class="active"><a href="pmd_languages_java.html">Java</a></li>
<li><a href="pmd_languages_js_ts.html">JavaScript / TypeScript</a></li>
<li><a href="pmd_languages_jsp.html">JSP</a></li>
<li><a href="pmd_languages_julia.html">Julia</a></li>
<li><a href="pmd_languages_kotlin.html">Kotlin</a></li>
<li><a href="pmd_languages_lua.html">Lua</a></li>
<li><a href="pmd_languages_matlab.html">Matlab</a></li>
<li><a href="pmd_languages_modelica.html">Modelica</a></li>
<li><a href="pmd_languages_objectivec.html">Objective-C</a></li>
<li><a href="pmd_languages_perl.html">Perl</a></li>
<li><a href="pmd_languages_php.html">PHP</a></li>
<li><a href="pmd_languages_plsql.html">PLSQL</a></li>
<li><a href="pmd_languages_python.html">Python</a></li>
<li><a href="pmd_languages_ruby.html">Ruby</a></li>
<li><a href="pmd_languages_scala.html">Scala</a></li>
<li><a href="pmd_languages_swift.html">Swift</a></li>
<li><a href="pmd_languages_tsql.html">T-SQL</a></li>
<li><a href="pmd_languages_visualforce.html">Visualforce</a></li>
<li><a href="pmd_languages_velocity.html">Velocity Template Language (VTL)</a></li>
<li><a href="pmd_languages_xml.html">XML and XML dialects</a></li>
</ul>
</li>
<li>
<a href="#">Developer Documentation</a>
<ul>
<li><a href="pmd_devdocs_development.html">Developer resources</a></li>
<li><a href="pmd_devdocs_building.html">Building PMD from source</a></li>
<li><a href="https://github.com/pmd/pmd/blob/main/CONTRIBUTING.md" target="_blank">Contributing</a></li>
<li><a href="pmd_devdocs_writing_documentation.html">Writing documentation</a></li>
<li><a href="pmd_devdocs_roadmap.html">Roadmap</a></li>
<li><a href="pmd_devdocs_how_pmd_works.html">How PMD works</a></li>
<li><a href="pmd_devdocs_pmdtester.html">Pmdtester</a></li>
<li><a href="pmd_devdocs_rule_deprecation_policy.html">Rule Deprecation Policy</a></li>
<li class="subfolders">
<a href="#">Major contributions</a>
<ul>
<li><a href="pmd_devdocs_major_rule_guidelines.html">Rule Guidelines</a></li>
<li><a href="pmd_devdocs_major_adding_new_language_javacc.html">Adding a new language (JavaCC)</a></li>
<li><a href="pmd_devdocs_major_adding_new_language_antlr.html">Adding a new language (ANTLR)</a></li>
<li><a href="pmd_devdocs_major_adding_new_cpd_language.html">Adding a new CPD language</a></li>
</ul>
</li>
<li class="subfolders">
<a href="#">Experimental features</a>
<ul>
<li><a href="tag_experimental.html">List of experimental Features</a></li>
</ul>
</li>
</ul>
</li>
<li>
<a href="#">Project documentation</a>
<ul>
<li class="subfolders">
<a href="#">Trivia about PMD</a>
<ul>
<li><a href="pmd_projectdocs_trivia_news.html">PMD in the press</a></li>
<li><a href="pmd_projectdocs_trivia_products.html">Products & books related to PMD</a></li>
<li><a href="pmd_projectdocs_trivia_similarprojects.html">Similar projects</a></li>
<li><a href="pmd_projectdocs_trivia_meaning.html">What does 'PMD' mean?</a></li>
</ul>
</li>
<li><a href="pmd_projectdocs_logo.html">Logo</a></li>
<li><a href="pmd_projectdocs_faq.html">FAQ</a></li>
<li><a href="license.html">License</a></li>
<li><a href="pmd_projectdocs_credits.html">Credits</a></li>
<li><a href="pmd_release_notes_old.html">Old release notes</a></li>
<li><a href="pmd_projectdocs_decisions.html">Decisions</a></li>
<li class="subfolders">
<a href="#">Project management</a>
<ul>
<li><a href="pmd_projectdocs_committers_infrastructure.html">Infrastructure</a></li>
<li><a href="pmd_projectdocs_committers_releasing.html">Release process</a></li>
<li><a href="pmd_projectdocs_committers_merging_pull_requests.html">Merging pull requests</a></li>
<li><a href="pmd_projectdocs_committers_main_landing_page.html">Main Landing page</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<!-- Content Column -->
<div class="col-md-9" id="tg-sb-content">
<header>
<div class="row">
<div class="col-lg-12">
<a href="./" role="button"
><i class="fa fa-home fa-lg"></i
></a>
» Java support
<a
target="_blank"
href="https://github.com/pmd/pmd/blob/main/docs/pages/pmd/languages/java.md"
class="float-right"
role="button"
><i class="fab fa-github fa-lg"></i> Edit on GitHub</a
>
</div>
</div>
<hr />
</header>
<div class="post-header">
<h1 class="post-title-main">Java support</h1>
</div>
<div class="post-content" data-github-edit-url="https://github.com/pmd/pmd/blob/main/docs/pages/pmd/languages/java.md">
<div class="summary">Java-specific features and guidance</div>
<details id="inline-toc-details">
<summary>Table of Contents</summary>
<div id="inline-toc"><!-- empty, move TOC here when screen size too small --></div>
</details>
<details class="language-info">
<summary>Language Info for Java
</summary>
<div class="card">
<ul class="list-group list-group-flush">
<li class="list-group-item">Since PMD 1.0.0</li>
<li class="list-group-item">Implementation: <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/JavaLanguageModule.html#"><code>JavaLanguageModule</code></a></li>
<li class="list-group-item">Id: java</li>
<li class="list-group-item">PMD: ✔️</li>
<li class="list-group-item">CPD: ✔️</li>
</ul>
</div>
</details>
<h2 id="overview-of-supported-java-language-versions">Overview of supported Java language versions</h2>
<p>Usually the latest non-preview Java Version is the default version.</p>
<table>
<thead>
<tr>
<th>Java Version</th>
<th>Alias</th>
<th>Supported by PMD since</th>
</tr>
</thead>
<tbody>
<tr>
<td>23-preview</td>
<td> </td>
<td>7.5.0</td>
</tr>
<tr>
<td>23 (default)</td>
<td> </td>
<td>7.5.0</td>
</tr>
<tr>
<td>22-preview</td>
<td> </td>
<td>7.0.0</td>
</tr>
<tr>
<td>22</td>
<td> </td>
<td>7.0.0</td>
</tr>
<tr>
<td>21</td>
<td> </td>
<td>7.0.0</td>
</tr>
<tr>
<td>20</td>
<td> </td>
<td>6.55.0</td>
</tr>
<tr>
<td>19</td>
<td> </td>
<td>6.48.0</td>
</tr>
<tr>
<td>18</td>
<td> </td>
<td>6.44.0</td>
</tr>
<tr>
<td>17</td>
<td> </td>
<td>6.37.0</td>
</tr>
<tr>
<td>16</td>
<td> </td>
<td>6.32.0</td>
</tr>
<tr>
<td>15</td>
<td> </td>
<td>6.27.0</td>
</tr>
<tr>
<td>14</td>
<td> </td>
<td>6.22.0</td>
</tr>
<tr>
<td>13</td>
<td> </td>
<td>6.18.0</td>
</tr>
<tr>
<td>12</td>
<td> </td>
<td>6.13.0</td>
</tr>
<tr>
<td>11</td>
<td> </td>
<td>6.6.0</td>
</tr>
<tr>
<td>10</td>
<td>1.10</td>
<td>6.4.0</td>
</tr>
<tr>
<td>9</td>
<td>1.9</td>
<td>6.0.0</td>
</tr>
<tr>
<td>8</td>
<td>1.8</td>
<td>5.1.0</td>
</tr>
<tr>
<td>7</td>
<td>1.7</td>
<td>5.0.0</td>
</tr>
<tr>
<td>6</td>
<td>1.6</td>
<td>3.9</td>
</tr>
<tr>
<td>5</td>
<td>1.5</td>
<td>3.0</td>
</tr>
<tr>
<td>1.4</td>
<td> </td>
<td>1.2.2</td>
</tr>
<tr>
<td>1.3</td>
<td> </td>
<td>1.0.0</td>
</tr>
</tbody>
</table>
<h2 id="using-java-preview-features">Using Java preview features</h2>
<p>In order to analyze a project with PMD that uses preview language features, youll need to enable
it via the environment variable <code class="language-plaintext highlighter-rouge">PMD_JAVA_OPTS</code> and select the new language version, e.g. <code class="language-plaintext highlighter-rouge">22-preview</code>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>export PMD_JAVA_OPTS=--enable-preview
pmd check --use-version java-22-preview ...
</code></pre></div></div>
<p>Note: we only support preview language features for the latest two java versions.</p>
<h2 id="language-properties">Language Properties</h2>
<p>See <a href="pmd_languages_configuration.html#java-language-properties">Java language properties</a></p>
<h2 id="type-and-symbol-resolution">Type and symbol resolution</h2>
<p>Java being a statically typed language, a Java program contains more information than just its syntax tree;
for instance, every expression has a static type, and every method call is bound to a method overload
statically (even if that overload is virtual). In PMD, much of this information is resolved from the AST
by additional passes, which run after parsing, and before rules can inspect the tree.</p>
<p>The semantic analysis roughly works like so:</p>
<ol>
<li>The first passes resolve <em>symbols</em>, which are a model of the named entities that Java programs declare,
like classes, methods, and variables.</li>
<li>Then, each name in the tree is resolved to a symbol, according to the languages scoping rules. This may
modify the tree to remove <em>ambiguous names</em> (names which could be either a type, package, or variable).</li>
<li>The last pass resolves the types of expressions, which performs overload resolution on method calls,
and type inference.</li>
</ol>
<p>The analyzed code might reference types from other places of the project or even from external
dependencies. If e.g. the code extends a class from an external dependency, then PMD needs to know
this external dependency in order to figure out, that a method is actually an override.</p>
<p>In order to resolve such types, a complete so-called auxiliary classpath need to be provided.
Technically, PMD uses the <a href="https://asm.ow2.io/index.html">ASM framework</a> to read the bytecode and build
up its own representation to resolve names and types. It also reads the bytecode of the Java runtime
in order to resolve Java API references.</p>
<h2 id="providing-the-auxiliary-classpath">Providing the auxiliary classpath</h2>
<p>The auxiliary classpath (or short “auxClasspath”) is configured via the
<a href="pmd_languages_configuration.html#java-language-properties">Language Property “auxClasspath”</a>.
It is a string containing multiple paths separated by either a colon (<code class="language-plaintext highlighter-rouge">:</code>) under Linux/MacOS
or a semicolon (<code class="language-plaintext highlighter-rouge">;</code>) under Windows. This property can be provided on the CLI with parameter
<a href="pmd_userdocs_cli_reference.html#-aux-classpath"><code class="language-plaintext highlighter-rouge">--aux-classpath</code></a>.</p>
<p>In order to resolve the types of the Java API correctly, the Java Runtime must be on the
auxClasspath as well. As the Java API and Runtime evolves from version to version, it is important
to use the correct Java version, that is being analyzed. This might not necessarily be the
same Java runtime version that is being used to run PMD.</p>
<p>Until Java 8, there exists the jar file <code class="language-plaintext highlighter-rouge">rt.jar</code> in <code class="language-plaintext highlighter-rouge">${JAVA_HOME}/jre/lib</code>. It is enough, to include
this jar file in the auxClasspath. Usually, you would add this as the first entry in the auxClasspath.</p>
<p>Beginning with Java 9, the Java platform has been modularized and <a href="https://openjdk.org/jeps/220">Modular Run-Time Images</a>
have been introduced. The file <code class="language-plaintext highlighter-rouge">${JAVA_HOME}/lib/modules</code> contains now all the classes, but it is not a jar file
anymore. However, each Java installation provides an implementation to read such Run-Time Images in
<code class="language-plaintext highlighter-rouge">${JAVA_HOME}/lib/jrt-fs.jar</code>. This is an implementation of the <code class="language-plaintext highlighter-rouge">jrt://</code> filesystem and through this, the bytecode
of the Java runtime classes can be loaded. In order to use this with PMD, the file <code class="language-plaintext highlighter-rouge">${JAVA_HOME}/lib/jrt-fs.jar</code>
needs to be added to the auxClasspath as the first entry. PMD will make sure, to load the Java runtime classes
using the jrt-filesystem.</p>
<p>If neither <code class="language-plaintext highlighter-rouge">${JAVA_HOME}/jre/lib/rt.jar</code> nor <code class="language-plaintext highlighter-rouge">${JAVA_HOME}/lib/jrt-fs.jar</code> is added to the auxClasspath, PMD falls
back to load the Java runtime classes <strong>from the current runtime</strong>, that is the runtime that was used to
execute PMD. This might not be the correct version, e.g. you might run PMD with Java 8, but analyze code
written for Java 21. In that case, you have to provide “jrt-fs.jar” on the auxClasspath.</p>
<p>Not providing the correct auxClasspath might result in false positives or negatives for some rules,
such as <a href="pmd_rules_java_bestpractices.html#missingoverride"><code class="language-plaintext highlighter-rouge">MissingOverride</code></a>.
This rule needs to figure out, whether a method is defined already in the super class or interface. E.g. the method
<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Collection.html#toArray(java.util.function.IntFunction)">Collection#toArray(IntFunction)</a>
has been added in Java 11, and it does not exist yet in Java 8. Given a simple subclass of ArrayList, that overrides
this method without adding <code class="language-plaintext highlighter-rouge">@Override</code>, then PMD wont be able to detect this missing override annotation, if
it is executed with a Java 8 runtime but without the correct auxClasspath. Providing the correct <code class="language-plaintext highlighter-rouge">jrt-fs.jar</code> from
Java 11 (or later) for the auxClasspath allows PMD to correctly identify the missing annotation.</p>
<p>Example command line:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pmd check -d src/main/java \
--aux-classpath=path/to/java17/lib/jrt-fs.jar:target/classes/ \
-f xml -r pmd-report.xml -R rulesets/java/quickstart.xml
</code></pre></div></div>
<h2 id="symbol-table-apis">Symbol table APIs</h2>
<p>Symbol table API related classes are in the package <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/symbols/package-summary.html#"><code>net.sourceforge.pmd.lang.java.symbols</code></a>.
The root interface for symbols is <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/symbols/JElementSymbol.html#"><code>JElementSymbol</code></a>.</p>
<p>The symbol table can be requested on any node with the method <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/AbstractJavaNode.html#getSymbolTable()"><code>getSymbolTable</code></a>.
This returns a <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/symbols/table/JSymbolTable.html#"><code>JSymbolTable</code></a> which gives you access to variables, methods and types that are
within scope.</p>
<p>A <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTExpression.html#"><code>ASTExpression</code></a> might represent a <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTAssignableExpr.ASTNamedReferenceExpr.html#"><code>ASTAssignableExpr.ASTNamedReferenceExpr</code></a>
if it e.g. references a variable name. In that case, you can access the referenced variable symbol
with the method <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTAssignableExpr.ASTNamedReferenceExpr.html#getReferencedSym()"><code>getReferencedSym</code></a>.</p>
<p>Declaration nodes, such as <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTVariableId.html#"><code>ASTVariableId</code></a> implement the interface
<a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/SymbolDeclaratorNode.html#"><code>SymbolDeclaratorNode</code></a>. Through the method
<a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/SymbolDeclaratorNode.html#getSymbol()"><code>getSymbol</code></a> you can also access the symbol.</p>
<p>To find usages, you can call <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTVariableId.html#getLocalUsages()"><code>getLocalUsages</code></a>.</p>
<h2 id="type-resolution-apis">Type resolution APIs</h2>
<p>Type resolution API related classes are in the package <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/types/package-summary.html#"><code>net.sourceforge.pmd.lang.java.types</code></a>.</p>
<p>The core of the framework is a set of interfaces to represent types. The root interface is
<a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/types/JTypeMirror.html#"><code>JTypeMirror</code></a>. Type mirrors are created by a
<a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/types/TypeSystem.html#"><code>TypeSystem</code></a> object. This object is analysis-global.</p>
<p>The utility class <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/types/TypeTestUtil.html#"><code>TypeTestUtil</code></a> provides simple methods to check types,
e.g. <code class="language-plaintext highlighter-rouge">TypeTestUtil.isA(String.class, variableDeclaratorIdNode)</code> tests, whether the given
variableDeclaratorId is of type “String”.</p>
<p>Any <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/TypeNode.html#"><code>TypeNode</code></a> provides access to the type with the method <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/TypeNode.html#getTypeMirror()"><code>getTypeMirror</code></a>.
E.g. this can be called on <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/ast/ASTMethodCall.html#"><code>ASTMethodCall</code></a> to retrieve the return type of the called method.</p>
<h2 id="metrics-framework">Metrics framework</h2>
<p>In order to use code metrics in Java, use the metrics constants in <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.html#"><code>JavaMetrics</code></a>,
together with <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.8.0-SNAPSHOT/net/sourceforge/pmd/lang/metrics/MetricsUtil.html#"><code>MetricsUtil</code></a>. For instance:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Override</span>
<span class="kd">public</span> <span class="nc">Object</span> <span class="nf">visit</span><span class="o">(</span><span class="nc">ASTMethodDeclaration</span> <span class="n">node</span><span class="o">,</span> <span class="nc">Object</span> <span class="n">data</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="nc">JavaMetrics</span><span class="o">.</span><span class="na">NCSS</span><span class="o">.</span><span class="na">supports</span><span class="o">(</span><span class="n">node</span><span class="o">))</span> <span class="o">{</span>
<span class="kt">int</span> <span class="n">methodSize</span> <span class="o">=</span> <span class="nc">MetricsUtil</span><span class="o">.</span><span class="na">computeMetric</span><span class="o">(</span><span class="nc">JavaMetrics</span><span class="o">.</span><span class="na">NCSS</span><span class="o">,</span> <span class="n">node</span><span class="o">,</span> <span class="n">ncssOptions</span><span class="o">);</span>
<span class="k">if</span> <span class="o">(</span><span class="n">methodSize</span> <span class="o">&gt;=</span> <span class="n">level</span><span class="o">)</span> <span class="o">{</span>
<span class="n">addViolation</span><span class="o">(</span><span class="n">data</span><span class="o">,</span> <span class="n">node</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">return</span> <span class="kc">null</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The Javadocs are the reference documentation.</p>
<h2 id="violation-decorators">Violation Decorators</h2>
<p>Violations reported are the same for all languages, but languages can opt in to provide more details.
Java does this by adding the following additional information for each reported violation:</p>
<ul>
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.8.0-SNAPSHOT/net/sourceforge/pmd/reporting/RuleViolation.html#VARIABLE_NAME"><code>VARIABLE_NAME</code></a></li>
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.8.0-SNAPSHOT/net/sourceforge/pmd/reporting/RuleViolation.html#METHOD_NAME"><code>METHOD_NAME</code></a></li>
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.8.0-SNAPSHOT/net/sourceforge/pmd/reporting/RuleViolation.html#CLASS_NAME"><code>CLASS_NAME</code></a></li>
<li><a href="https://docs.pmd-code.org/apidocs/pmd-core/7.8.0-SNAPSHOT/net/sourceforge/pmd/reporting/RuleViolation.html#PACKAGE_NAME"><code>PACKAGE_NAME</code></a></li>
</ul>
<p>You can access these via <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.8.0-SNAPSHOT/net/sourceforge/pmd/reporting/RuleViolation.html#getAdditionalInfo()"><code>getAdditionalInfo</code></a></p>
<h2 id="dataflow">Dataflow</h2>
<p>There is no API yet for dataflow analysis. However, some rules such as <a href="pmd_rules_java_bestpractices.html#unusedassignment"><code class="language-plaintext highlighter-rouge">UnusedAssignment</code></a>
or <a href="pmd_rules_java_design.html#immutablefield"><code class="language-plaintext highlighter-rouge">ImmutableField</code></a> are using an internal implementation of an additional
AST pass that adds dataflow information. The implementation can be found in
<a href="https://github.com/pmd/pmd/blob/main/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java">net.sourceforge.pmd.lang.java.rule.internal.DataflowPass</a>.</p>
<div class="tags">
<b>Tags: </b>
<a href="tag_languages.html" class="btn btn-outline-secondary navbar-btn cursorNorm" role="button">languages</a>
<a href="tag_PmdCapableLanguage.html" class="btn btn-outline-secondary navbar-btn cursorNorm" role="button">PmdCapableLanguage</a>
<a href="tag_CpdCapableLanguage.html" class="btn btn-outline-secondary navbar-btn cursorNorm" role="button">CpdCapableLanguage</a>
</div>
</div>
<footer>
<hr />
<div>
This documentation is written in markdown. <br />
If there is something missing or can be improved, edit this page on
github and create a PR:
<a
target="_blank"
href="https://github.com/pmd/pmd/blob/main/docs/pages/pmd/languages/java.md"
role="button"
><i class="fab fa-github fa-lg"></i> Edit on GitHub</a
>
</div>
<hr />
<div class="row">
<div class="col-lg-12 footer">
&copy;2024 PMD Open Source Project. All rights
reserved. <br />
<span>Page last updated:</span>
July 2024 (7.5.0)<br /> Site last generated: Nov 21, 2024 <br />
<p>
<img src="images/logo/pmd-logo-70px.png" alt="PMD
logo"/>
</p>
</div>
</div>
</footer>
</div>
<!-- /.row -->
</div>
<!-- /.container -->
</div>
<!-- Sticky TOC column -->
<div class="toc-col">
<div id="toc"></div>
</div>
<!-- /.toc-container-wrapper -->
</div>
</div>
<script type="application/javascript" src="assets/jquery-3.5.1/jquery-3.5.1.min.js"></script>
<script type="application/javascript" src="assets/anchorjs-4.2.2/anchor.min.js"></script>
<script type="application/javascript" src="assets/navgoco-0.2.1/src/jquery.navgoco.min.js"></script>
<script type="application/javascript" src="assets/bootstrap-4.5.2-dist/js/bootstrap.bundle.min.js"></script>
<script type="application/javascript" src="assets/Simple-Jekyll-Search-1.0.8/dest/jekyll-search.js"></script>
<script type="application/javascript" src="assets/jekyll-table-of-contents/toc.js"></script>
<script type="application/javascript" src="js/tabstate.js"></script>
<script type="application/javascript" src="js/customscripts.js"></script>
</body>
</html>