foo )
+ {
+ }
+
+}
diff --git a/src/it/MPMD-379-JDK21/verify.groovy b/src/it/MPMD-379-JDK21/verify.groovy
new file mode 100644
index 00000000..2846ad3c
--- /dev/null
+++ b/src/it/MPMD-379-JDK21/verify.groovy
@@ -0,0 +1,24 @@
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+File buildLog = new File( basedir, 'build.log' )
+assert buildLog.exists()
+assert buildLog.text.contains( '[INFO] PMD Failure: com.mycompany.app.Foo:26 Rule:UnusedFormalParameter Priority:3' )
+assert !buildLog.text.contains( '[WARNING] PMD' )
diff --git a/src/it/MPMD-89-232-typeresolution/src/main/pmd/ruleset.xml b/src/it/MPMD-89-232-typeresolution/src/main/pmd/ruleset.xml
index fcd6bc40..05c8abdc 100644
--- a/src/it/MPMD-89-232-typeresolution/src/main/pmd/ruleset.xml
+++ b/src/it/MPMD-89-232-typeresolution/src/main/pmd/ruleset.xml
@@ -24,5 +24,5 @@ under the License.
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
Custom Ruleset for test case MPMD-89 and MPMP-232
-
+
diff --git a/src/it/mpmd-138/verify.groovy b/src/it/mpmd-138/verify.groovy
index 0a3a32bd..b9dc0f75 100644
--- a/src/it/mpmd-138/verify.groovy
+++ b/src/it/mpmd-138/verify.groovy
@@ -23,7 +23,7 @@ assert buildLog.exists()
// Module 1
assert 1 == buildLog.getText().count('[INFO] PMD Failure: test.MyClass:27 Rule:UnnecessarySemicolon Priority:3 Unnecessary semicolon')
-assert 1 == buildLog.getText().count('[INFO] PMD Failure: test.MyClass:28 Rule:UnnecessaryReturn Priority:3 Avoid unnecessary return statements')
+assert 1 == buildLog.getText().count('[INFO] PMD Failure: test.MyClass:28 Rule:UnnecessaryReturn Priority:3 Unnecessary return statement')
assert 1 == buildLog.getText().count('[INFO] You have 2 PMD violations. For more details see:')
// Module 2
@@ -34,4 +34,4 @@ assert 1 == buildLog.getText().count('[INFO] You have 1 PMD violation. For more
assert 1 == buildLog.getText().count('[INFO] You have 1 CPD duplication. For more details see:')
// Module 4
-assert 1 == buildLog.getText().count('[INFO] You have 2 CPD duplications. For more details see:')
\ No newline at end of file
+assert 1 == buildLog.getText().count('[INFO] You have 2 CPD duplications. For more details see:')
diff --git a/src/it/multi-module/mod-1/src/main/config/pmd/utf-8.xml b/src/it/multi-module/mod-1/src/main/config/pmd/utf-8.xml
index 32ad7868..8e4fc166 100644
--- a/src/it/multi-module/mod-1/src/main/config/pmd/utf-8.xml
+++ b/src/it/multi-module/mod-1/src/main/config/pmd/utf-8.xml
@@ -23,5 +23,5 @@ under the License.
This ruleset is encoded with UTF-8 to check proper encoding handling.
-
+
diff --git a/src/it/multi-module/mod-2/rulesets/java/basic.xml b/src/it/multi-module/mod-2/rulesets/java/basic.xml
index 1bf26926..8274fe41 100644
--- a/src/it/multi-module/mod-2/rulesets/java/basic.xml
+++ b/src/it/multi-module/mod-2/rulesets/java/basic.xml
@@ -23,5 +23,5 @@ under the License.
The relative path of this ruleset matches the built-in ruleset "basic".
-
+
diff --git a/src/it/multi-module/mod-3/src/main/config/pmd/rel.xml b/src/it/multi-module/mod-3/src/main/config/pmd/rel.xml
index 05fa23cb..08b4a638 100644
--- a/src/it/multi-module/mod-3/src/main/config/pmd/rel.xml
+++ b/src/it/multi-module/mod-3/src/main/config/pmd/rel.xml
@@ -23,5 +23,5 @@ under the License.
This ruleset is specified via a relative filesystem path.
-
+
diff --git a/src/main/java/org/apache/maven/plugins/pmd/AbstractPmdReport.java b/src/main/java/org/apache/maven/plugins/pmd/AbstractPmdReport.java
index 4fd2a54f..87c40d85 100644
--- a/src/main/java/org/apache/maven/plugins/pmd/AbstractPmdReport.java
+++ b/src/main/java/org/apache/maven/plugins/pmd/AbstractPmdReport.java
@@ -196,10 +196,20 @@ public abstract class AbstractPmdReport extends AbstractMavenReport {
* the PMD logger is also configured for debug.
*
* @since 3.9.0
+ * @deprecated With 3.22.0 and the upgrade to PMD 7, this parameter has no effect anymore. The PMD log
+ * is now always redirected into the maven log and this can't be disabled by this parameter anymore.
+ * In order to disable the logging, see Maven Logging.
+ * You'd need to start maven with MAVEN_OPTS=-Dorg.slf4j.simpleLogger.log.net.sourceforge.pmd=off mvn <goals>
.
*/
@Parameter(defaultValue = "true", property = "pmd.showPmdLog")
+ @Deprecated // (since = "3.22.0", forRemoval = true)
protected boolean showPmdLog = true;
+ /**
+ * Used to avoid showing the deprecation warning for "showPmdLog" multiple times.
+ */
+ private boolean warnedAboutShowPmdLog = false;
+
/**
*
* Allow for configuration of the jvm used to run PMD via maven toolchains.
@@ -454,6 +464,12 @@ protected boolean isXml() {
*/
@Override
public boolean canGenerateReport() {
+ if (!showPmdLog && !warnedAboutShowPmdLog) {
+ getLog().warn("The parameter \"showPmdLog\" has been deprecated and will be removed."
+ + "Setting it to \"false\" has no effect.");
+ warnedAboutShowPmdLog = true;
+ }
+
if (aggregate && !project.isExecutionRoot()) {
return false;
}
diff --git a/src/main/java/org/apache/maven/plugins/pmd/CpdReport.java b/src/main/java/org/apache/maven/plugins/pmd/CpdReport.java
index c01fdbc4..8c003641 100644
--- a/src/main/java/org/apache/maven/plugins/pmd/CpdReport.java
+++ b/src/main/java/org/apache/maven/plugins/pmd/CpdReport.java
@@ -21,10 +21,7 @@
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Locale;
-import java.util.Properties;
-import net.sourceforge.pmd.cpd.JavaTokenizer;
-import net.sourceforge.pmd.cpd.renderer.CPDRenderer;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
@@ -177,29 +174,18 @@ private void executeCpd() throws MavenReportException {
return;
}
- Properties languageProperties = new Properties();
- if (ignoreLiterals) {
- languageProperties.setProperty(JavaTokenizer.IGNORE_LITERALS, "true");
- }
- if (ignoreIdentifiers) {
- languageProperties.setProperty(JavaTokenizer.IGNORE_IDENTIFIERS, "true");
- }
- if (ignoreAnnotations) {
- languageProperties.setProperty(JavaTokenizer.IGNORE_ANNOTATIONS, "true");
- }
try {
filesToProcess = getFilesToProcess();
CpdRequest request = new CpdRequest();
request.setMinimumTokens(minimumTokens);
request.setLanguage(language);
- request.setLanguageProperties(languageProperties);
+ request.setIgnoreAnnotations(ignoreAnnotations);
+ request.setIgnoreIdentifiers(ignoreIdentifiers);
+ request.setIgnoreLiterals(ignoreLiterals);
request.setSourceEncoding(getInputEncoding());
request.addFiles(filesToProcess.keySet());
-
- request.setShowPmdLog(showPmdLog);
request.setLogLevel(determineCurrentRootLogLevel());
-
request.setExcludeFromFailureFile(excludeFromFailureFile);
request.setTargetDirectory(targetDirectory.getAbsolutePath());
request.setOutputEncoding(getOutputEncoding());
@@ -229,16 +215,4 @@ private void executeCpd() throws MavenReportException {
public String getOutputName() {
return "cpd";
}
-
- /**
- * Create and return the correct renderer for the output type.
- *
- * @return the renderer based on the configured output
- * @throws org.apache.maven.reporting.MavenReportException if no renderer found for the output type
- * @deprecated Use {@link CpdExecutor#createRenderer(String, String)} instead.
- */
- @Deprecated
- public CPDRenderer createRenderer() throws MavenReportException {
- return CpdExecutor.createRenderer(format, getOutputEncoding());
- }
}
diff --git a/src/main/java/org/apache/maven/plugins/pmd/ExcludeDuplicationsFromFile.java b/src/main/java/org/apache/maven/plugins/pmd/ExcludeDuplicationsFromFile.java
index ea199a8c..87fff0a6 100644
--- a/src/main/java/org/apache/maven/plugins/pmd/ExcludeDuplicationsFromFile.java
+++ b/src/main/java/org/apache/maven/plugins/pmd/ExcludeDuplicationsFromFile.java
@@ -64,7 +64,7 @@ public boolean isExcludedFromFailure(final Duplication errorDetail) {
public boolean isExcludedFromFailure(final Match errorDetail) {
final Set uniquePaths = new HashSet<>();
for (Mark mark : errorDetail.getMarkSet()) {
- uniquePaths.add(mark.getFilename());
+ uniquePaths.add(mark.getLocation().getFileId().getAbsolutePath());
}
return isExcludedFromFailure(uniquePaths);
}
diff --git a/src/main/java/org/apache/maven/plugins/pmd/ExcludeViolationsFromFile.java b/src/main/java/org/apache/maven/plugins/pmd/ExcludeViolationsFromFile.java
index 38919a48..da5a7db5 100644
--- a/src/main/java/org/apache/maven/plugins/pmd/ExcludeViolationsFromFile.java
+++ b/src/main/java/org/apache/maven/plugins/pmd/ExcludeViolationsFromFile.java
@@ -28,7 +28,7 @@
import java.util.Properties;
import java.util.Set;
-import net.sourceforge.pmd.RuleViolation;
+import net.sourceforge.pmd.reporting.RuleViolation;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.pmd.model.Violation;
@@ -84,8 +84,11 @@ public boolean isExcludedFromFailure(final Violation errorDetail) {
* @return true
if the violation should be excluded, false
otherwise.
*/
public boolean isExcludedFromFailure(final RuleViolation errorDetail) {
- final String className =
- extractClassName(errorDetail.getPackageName(), errorDetail.getClassName(), errorDetail.getFilename());
+ final Map additionalInfo = errorDetail.getAdditionalInfo();
+ final String className = extractClassName(
+ additionalInfo.get(RuleViolation.PACKAGE_NAME),
+ additionalInfo.get(RuleViolation.CLASS_NAME),
+ errorDetail.getFileId().getAbsolutePath());
return isExcludedFromFailure(className, errorDetail.getRule().getName());
}
diff --git a/src/main/java/org/apache/maven/plugins/pmd/PmdReport.java b/src/main/java/org/apache/maven/plugins/pmd/PmdReport.java
index bd41e278..5b3a14c8 100644
--- a/src/main/java/org/apache/maven/plugins/pmd/PmdReport.java
+++ b/src/main/java/org/apache/maven/plugins/pmd/PmdReport.java
@@ -63,14 +63,14 @@
@Mojo(name = "pmd", threadSafe = true, requiresDependencyResolution = ResolutionScope.TEST)
public class PmdReport extends AbstractPmdReport {
/**
- * The target JDK to analyze based on. Should match the source used in the compiler plugin. Valid values
- * with the default PMD version are
- * currently 1.3
, 1.4
, 1.5
, 1.6
, 1.7
,
- * 1.8
, 9
, 10
, 11
, 12
, 13
,
- * 14
, 15
, 16
, 17
, 18
, 19
,
- * and 20
.
+ * The target JDK to analyze based on. Should match the source used in the compiler plugin.
+ * Valid values depend on the used PMD version. Most common values are
+ * 8
, 11
, 17
, and 21
.
*
- * You can override the default PMD version by specifying PMD as a dependency,
+ *
The full list of supported Java versions for each PMD version is available at
+ * Java support (PMD).
+ *
+ * You can override the default PMD version by specifying PMD as a dependency,
* see Upgrading PMD at Runtime.
*
*
@@ -366,11 +366,9 @@ private void executePmd() throws MavenReportException {
request.setBenchmarkOutputLocation(benchmark ? benchmarkOutputFilename : null);
request.setAnalysisCacheLocation(analysisCache ? analysisCacheLocation : null);
request.setExcludeFromFailureFile(excludeFromFailureFile);
-
request.setTargetDirectory(targetDirectory.getAbsolutePath());
request.setOutputEncoding(getOutputEncoding());
request.setFormat(format);
- request.setShowPmdLog(showPmdLog);
request.setSkipPmdError(skipPmdError);
request.setIncludeXmlInSite(includeXmlInSite);
request.setReportOutputDirectory(getReportOutputDirectory().getAbsolutePath());
diff --git a/src/main/java/org/apache/maven/plugins/pmd/PmdReportRenderer.java b/src/main/java/org/apache/maven/plugins/pmd/PmdReportRenderer.java
index 1665f2c9..d961eebb 100644
--- a/src/main/java/org/apache/maven/plugins/pmd/PmdReportRenderer.java
+++ b/src/main/java/org/apache/maven/plugins/pmd/PmdReportRenderer.java
@@ -30,7 +30,7 @@
import java.util.Locale;
import java.util.Map;
-import net.sourceforge.pmd.RulePriority;
+import net.sourceforge.pmd.lang.rule.RulePriority;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.pmd.model.ProcessingError;
diff --git a/src/main/java/org/apache/maven/plugins/pmd/exec/CpdExecutor.java b/src/main/java/org/apache/maven/plugins/pmd/exec/CpdExecutor.java
index 43ba3c06..3cdd5758 100644
--- a/src/main/java/org/apache/maven/plugins/pmd/exec/CpdExecutor.java
+++ b/src/main/java/org/apache/maven/plugins/pmd/exec/CpdExecutor.java
@@ -26,23 +26,19 @@
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
+import java.nio.charset.Charset;
import java.util.Objects;
+import java.util.function.Predicate;
-import net.sourceforge.pmd.cpd.CPD;
import net.sourceforge.pmd.cpd.CPDConfiguration;
+import net.sourceforge.pmd.cpd.CPDReport;
+import net.sourceforge.pmd.cpd.CPDReportRenderer;
import net.sourceforge.pmd.cpd.CSVRenderer;
-import net.sourceforge.pmd.cpd.EcmascriptLanguage;
-import net.sourceforge.pmd.cpd.JSPLanguage;
-import net.sourceforge.pmd.cpd.JavaLanguage;
-import net.sourceforge.pmd.cpd.Language;
-import net.sourceforge.pmd.cpd.LanguageFactory;
+import net.sourceforge.pmd.cpd.CpdAnalysis;
import net.sourceforge.pmd.cpd.Match;
import net.sourceforge.pmd.cpd.SimpleRenderer;
import net.sourceforge.pmd.cpd.XMLRenderer;
-import net.sourceforge.pmd.cpd.renderer.CPDRenderer;
+import net.sourceforge.pmd.lang.Language;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.pmd.ExcludeDuplicationsFromFile;
import org.apache.maven.reporting.MavenReportException;
@@ -145,8 +141,6 @@ public CpdExecutor(CpdRequest request) {
}
private CpdResult run() throws MavenReportException {
- setupPmdLogging(request.isShowPmdLog(), request.getLogLevel());
-
try {
excludeDuplicationsFromFile.loadExcludeFromFailuresData(request.getExcludeFromFailureFile());
} catch (MojoExecutionException e) {
@@ -155,46 +149,50 @@ private CpdResult run() throws MavenReportException {
CPDConfiguration cpdConfiguration = new CPDConfiguration();
cpdConfiguration.setMinimumTileSize(request.getMinimumTokens());
+ cpdConfiguration.setIgnoreAnnotations(request.isIgnoreAnnotations());
+ cpdConfiguration.setIgnoreLiterals(request.isIgnoreLiterals());
+ cpdConfiguration.setIgnoreIdentifiers(request.isIgnoreIdentifiers());
- Language cpdLanguage;
- if ("java".equals(request.getLanguage()) || null == request.getLanguage()) {
- cpdLanguage = new JavaLanguage(request.getLanguageProperties());
- } else if ("javascript".equals(request.getLanguage())) {
- cpdLanguage = new EcmascriptLanguage();
- } else if ("jsp".equals(request.getLanguage())) {
- cpdLanguage = new JSPLanguage();
- } else {
- cpdLanguage = LanguageFactory.createLanguage(request.getLanguage(), request.getLanguageProperties());
+ String languageId = request.getLanguage();
+ if ("javascript".equals(languageId)) {
+ languageId = "ecmascript";
+ } else if (languageId == null) {
+ languageId = "java"; // default
}
+ Language cpdLanguage = cpdConfiguration.getLanguageRegistry().getLanguageById(languageId);
- cpdConfiguration.setLanguage(cpdLanguage);
- cpdConfiguration.setSourceEncoding(request.getSourceEncoding());
+ cpdConfiguration.setOnlyRecognizeLanguage(cpdLanguage);
+ cpdConfiguration.setSourceEncoding(Charset.forName(request.getSourceEncoding()));
- CPD cpd = new CPD(cpdConfiguration);
- try {
- cpd.add(request.getFiles());
- } catch (IOException e) {
- throw new MavenReportException(e.getMessage(), e);
- }
+ request.getFiles().forEach(f -> cpdConfiguration.addInputPath(f.toPath()));
LOG.debug("Executing CPD...");
- cpd.go();
- LOG.debug("CPD finished.");
// always create XML format. we need to output it even if the file list is empty or we have no duplications
// so the "check" goals can check for violations
- writeXmlReport(cpd);
+ try (CpdAnalysis cpd = CpdAnalysis.create(cpdConfiguration)) {
+ cpd.performAnalysis(report -> {
+ try {
+ writeXmlReport(report);
- // html format is handled by maven site report, xml format has already been rendered
- String format = request.getFormat();
- if (!"html".equals(format) && !"xml".equals(format)) {
- writeFormattedReport(cpd);
+ // html format is handled by maven site report, xml format has already been rendered
+ String format = request.getFormat();
+ if (!"html".equals(format) && !"xml".equals(format)) {
+ writeFormattedReport(report);
+ }
+ } catch (MavenReportException e) {
+ LOG.error("Error while writing CPD report", e);
+ }
+ });
+ } catch (IOException e) {
+ LOG.error("Error while executing CPD", e);
}
+ LOG.debug("CPD finished.");
return new CpdResult(new File(request.getTargetDirectory(), "cpd.xml"), request.getOutputEncoding());
}
- private void writeXmlReport(CPD cpd) throws MavenReportException {
+ private void writeXmlReport(CPDReport cpd) throws MavenReportException {
File targetFile = writeReport(cpd, new XMLRenderer(request.getOutputEncoding()), "xml");
if (request.isIncludeXmlInSite()) {
File siteDir = new File(request.getReportOutputDirectory());
@@ -207,7 +205,7 @@ private void writeXmlReport(CPD cpd) throws MavenReportException {
}
}
- private File writeReport(CPD cpd, CPDRenderer r, String extension) throws MavenReportException {
+ private File writeReport(CPDReport cpd, CPDReportRenderer r, String extension) throws MavenReportException {
if (r == null) {
return null;
}
@@ -216,7 +214,7 @@ private File writeReport(CPD cpd, CPDRenderer r, String extension) throws MavenR
targetDir.mkdirs();
File targetFile = new File(targetDir, "cpd." + extension);
try (Writer writer = new OutputStreamWriter(new FileOutputStream(targetFile), request.getOutputEncoding())) {
- r.render(filterMatches(cpd.getMatches()), writer);
+ r.render(cpd.filterMatches(filterMatches()), writer);
writer.flush();
} catch (IOException ioe) {
throw new MavenReportException(ioe.getMessage(), ioe);
@@ -224,8 +222,8 @@ private File writeReport(CPD cpd, CPDRenderer r, String extension) throws MavenR
return targetFile;
}
- private void writeFormattedReport(CPD cpd) throws MavenReportException {
- CPDRenderer r = createRenderer(request.getFormat(), request.getOutputEncoding());
+ private void writeFormattedReport(CPDReport cpd) throws MavenReportException {
+ CPDReportRenderer r = createRenderer(request.getFormat(), request.getOutputEncoding());
writeReport(cpd, r, request.getFormat());
}
@@ -235,8 +233,8 @@ private void writeFormattedReport(CPD cpd) throws MavenReportException {
* @return the renderer based on the configured output
* @throws org.apache.maven.reporting.MavenReportException if no renderer found for the output type
*/
- public static CPDRenderer createRenderer(String format, String outputEncoding) throws MavenReportException {
- CPDRenderer renderer = null;
+ public static CPDReportRenderer createRenderer(String format, String outputEncoding) throws MavenReportException {
+ CPDReportRenderer renderer = null;
if ("xml".equals(format)) {
renderer = new XMLRenderer(outputEncoding);
} else if ("csv".equals(format)) {
@@ -245,7 +243,8 @@ public static CPDRenderer createRenderer(String format, String outputEncoding) t
renderer = new SimpleRenderer();
} else if (!"".equals(format) && !"none".equals(format)) {
try {
- renderer = (CPDRenderer) Class.forName(format).getConstructor().newInstance();
+ renderer = (CPDReportRenderer)
+ Class.forName(format).getConstructor().newInstance();
} catch (Exception e) {
throw new MavenReportException(
"Can't find CPD custom format " + format + ": "
@@ -257,22 +256,17 @@ public static CPDRenderer createRenderer(String format, String outputEncoding) t
return renderer;
}
- private Iterator filterMatches(Iterator matches) {
- LOG.debug("Filtering duplications. Using " + excludeDuplicationsFromFile.countExclusions()
- + " configured exclusions.");
+ private Predicate filterMatches() {
+ return (Match match) -> {
+ LOG.debug("Filtering duplications. Using " + excludeDuplicationsFromFile.countExclusions()
+ + " configured exclusions.");
- List filteredMatches = new ArrayList<>();
- int excludedDuplications = 0;
- while (matches.hasNext()) {
- Match match = matches.next();
if (excludeDuplicationsFromFile.isExcludedFromFailure(match)) {
- excludedDuplications++;
+ LOG.debug("Excluded " + match + " duplications.");
+ return false;
} else {
- filteredMatches.add(match);
+ return true;
}
- }
-
- LOG.debug("Excluded " + excludedDuplications + " duplications.");
- return filteredMatches.iterator();
+ };
}
}
diff --git a/src/main/java/org/apache/maven/plugins/pmd/exec/CpdRequest.java b/src/main/java/org/apache/maven/plugins/pmd/exec/CpdRequest.java
index ebbff049..7ecc7109 100644
--- a/src/main/java/org/apache/maven/plugins/pmd/exec/CpdRequest.java
+++ b/src/main/java/org/apache/maven/plugins/pmd/exec/CpdRequest.java
@@ -44,7 +44,6 @@ public class CpdRequest implements Serializable {
private String sourceEncoding;
private List files = new ArrayList<>();
- private boolean showPmdLog;
private String logLevel;
private String excludeFromFailureFile;
@@ -53,6 +52,9 @@ public class CpdRequest implements Serializable {
private String format;
private boolean includeXmlInSite;
private String reportOutputDirectory;
+ private boolean ignoreAnnotations;
+ private boolean ignoreIdentifiers;
+ private boolean ignoreLiterals;
public void setJavaExecutable(String javaExecutable) {
this.javaExecutable = javaExecutable;
@@ -102,10 +104,6 @@ public void setReportOutputDirectory(String reportOutputDirectory) {
this.reportOutputDirectory = reportOutputDirectory;
}
- public void setShowPmdLog(boolean showPmdLog) {
- this.showPmdLog = showPmdLog;
- }
-
public void setLogLevel(String logLevel) {
this.logLevel = logLevel;
}
@@ -158,11 +156,31 @@ public String getReportOutputDirectory() {
return reportOutputDirectory;
}
- public boolean isShowPmdLog() {
- return showPmdLog;
- }
-
public String getLogLevel() {
return logLevel;
}
+
+ public boolean isIgnoreAnnotations() {
+ return ignoreAnnotations;
+ }
+
+ public void setIgnoreAnnotations(boolean ignoreAnnotations) {
+ this.ignoreAnnotations = ignoreAnnotations;
+ }
+
+ public void setIgnoreIdentifiers(boolean ignoreIdentifiers) {
+ this.ignoreIdentifiers = ignoreIdentifiers;
+ }
+
+ public boolean isIgnoreIdentifiers() {
+ return ignoreIdentifiers;
+ }
+
+ public void setIgnoreLiterals(boolean ignoreLiterals) {
+ this.ignoreLiterals = ignoreLiterals;
+ }
+
+ public boolean isIgnoreLiterals() {
+ return ignoreLiterals;
+ }
}
diff --git a/src/main/java/org/apache/maven/plugins/pmd/exec/Executor.java b/src/main/java/org/apache/maven/plugins/pmd/exec/Executor.java
index d8f902c0..e128f7c1 100644
--- a/src/main/java/org/apache/maven/plugins/pmd/exec/Executor.java
+++ b/src/main/java/org/apache/maven/plugins/pmd/exec/Executor.java
@@ -29,9 +29,6 @@
import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
-import java.util.logging.Handler;
-import java.util.logging.Level;
-import java.util.logging.SimpleFormatter;
import org.apache.maven.cli.logging.Slf4jConfiguration;
import org.apache.maven.cli.logging.Slf4jConfigurationFactory;
@@ -39,48 +36,10 @@
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.slf4j.bridge.SLF4JBridgeHandler;
abstract class Executor {
private static final Logger LOG = LoggerFactory.getLogger(Executor.class);
- /**
- * This holds a strong reference in case we configured the logger to
- * redirect to slf4j. See {@link #showPmdLog}. Without a strong reference,
- * the logger might be garbage collected and the redirect to slf4j is gone.
- */
- private java.util.logging.Logger julLogger;
-
- protected void setupPmdLogging(boolean showPmdLog, String logLevel) {
- if (!showPmdLog) {
- return;
- }
-
- java.util.logging.Logger logger = java.util.logging.Logger.getLogger("net.sourceforge.pmd");
-
- boolean slf4jBridgeAlreadyAdded = false;
- for (Handler handler : logger.getHandlers()) {
- if (handler instanceof SLF4JBridgeHandler) {
- slf4jBridgeAlreadyAdded = true;
- break;
- }
- }
-
- if (slf4jBridgeAlreadyAdded) {
- return;
- }
-
- SLF4JBridgeHandler handler = new SLF4JBridgeHandler();
- SimpleFormatter formatter = new SimpleFormatter();
- handler.setFormatter(formatter);
- logger.setUseParentHandlers(false);
- logger.addHandler(handler);
- handler.setLevel(Level.ALL);
- logger.setLevel(Level.ALL);
- julLogger = logger;
- julLogger.fine("Configured jul-to-slf4j bridge for " + logger.getName());
- }
-
protected void setupLogLevel(String logLevel) {
ILoggerFactory slf4jLoggerFactory = LoggerFactory.getILoggerFactory();
Slf4jConfiguration slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration(slf4jLoggerFactory);
diff --git a/src/main/java/org/apache/maven/plugins/pmd/exec/PmdExecutor.java b/src/main/java/org/apache/maven/plugins/pmd/exec/PmdExecutor.java
index 8e96bf41..e6dacdbe 100644
--- a/src/main/java/org/apache/maven/plugins/pmd/exec/PmdExecutor.java
+++ b/src/main/java/org/apache/maven/plugins/pmd/exec/PmdExecutor.java
@@ -27,30 +27,28 @@
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
+import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import net.sourceforge.pmd.PMDConfiguration;
import net.sourceforge.pmd.PmdAnalysis;
-import net.sourceforge.pmd.Report;
-import net.sourceforge.pmd.RulePriority;
-import net.sourceforge.pmd.RuleSetLoadException;
-import net.sourceforge.pmd.RuleSetLoader;
-import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.benchmark.TextTimingReportRenderer;
import net.sourceforge.pmd.benchmark.TimeTracker;
import net.sourceforge.pmd.benchmark.TimingReport;
import net.sourceforge.pmd.benchmark.TimingReportRenderer;
import net.sourceforge.pmd.lang.Language;
-import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.LanguageVersion;
+import net.sourceforge.pmd.lang.rule.RulePriority;
+import net.sourceforge.pmd.lang.rule.RuleSetLoadException;
+import net.sourceforge.pmd.lang.rule.RuleSetLoader;
import net.sourceforge.pmd.renderers.CSVRenderer;
import net.sourceforge.pmd.renderers.HTMLRenderer;
import net.sourceforge.pmd.renderers.Renderer;
import net.sourceforge.pmd.renderers.TextRenderer;
import net.sourceforge.pmd.renderers.XMLRenderer;
-import net.sourceforge.pmd.util.Predicate;
+import net.sourceforge.pmd.reporting.Report;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.pmd.ExcludeViolationsFromFile;
import org.apache.maven.reporting.MavenReportException;
@@ -151,12 +149,11 @@ public PmdExecutor(PmdRequest request) {
}
private PmdResult run() throws MavenReportException {
- setupPmdLogging(request.isShowPmdLog(), request.getLogLevel());
-
PMDConfiguration configuration = new PMDConfiguration();
LanguageVersion languageVersion = null;
- Language language = LanguageRegistry.findLanguageByTerseName(
- request.getLanguage() != null ? request.getLanguage() : "java");
+ Language language = configuration
+ .getLanguageRegistry()
+ .getLanguageById(request.getLanguage() != null ? request.getLanguage() : "java");
if (language == null) {
throw new MavenReportException("Unsupported language: " + request.getLanguage());
}
@@ -172,7 +169,7 @@ private PmdResult run() throws MavenReportException {
configuration.setDefaultLanguageVersion(languageVersion);
if (request.getSourceEncoding() != null) {
- configuration.setSourceEncoding(request.getSourceEncoding());
+ configuration.setSourceEncoding(Charset.forName(request.getSourceEncoding()));
}
configuration.prependAuxClasspath(request.getAuxClasspath());
@@ -190,7 +187,7 @@ private PmdResult run() throws MavenReportException {
configuration.setRuleSets(request.getRulesets());
configuration.setMinimumPriority(RulePriority.valueOf(request.getMinimumPriority()));
if (request.getBenchmarkOutputLocation() != null) {
- configuration.setBenchmark(true);
+ TimeTracker.startGlobalTracking();
}
List files = request.getFiles();
@@ -262,7 +259,7 @@ private PmdResult run() throws MavenReportException {
private String getErrorsAsString(List errors, boolean withDetails) {
List errorsAsString = new ArrayList<>(errors.size());
for (Report.ProcessingError error : errors) {
- errorsAsString.add(error.getFile() + ": " + error.getMsg());
+ errorsAsString.add(error.getFileId().getAbsolutePath() + ": " + error.getMsg());
if (withDetails) {
errorsAsString.add(error.getDetail());
}
@@ -413,12 +410,8 @@ private Report removeExcludedViolations(Report report) throws MavenReportExcepti
LOG.debug("Removing excluded violations. Using {} configured exclusions.", excludeFromFile.countExclusions());
int violationsBefore = report.getViolations().size();
- Report filtered = report.filterViolations(new Predicate() {
- @Override
- public boolean test(RuleViolation ruleViolation) {
- return !excludeFromFile.isExcludedFromFailure(ruleViolation);
- }
- });
+ Report filtered =
+ report.filterViolations(ruleViolation -> !excludeFromFile.isExcludedFromFailure(ruleViolation));
int numberOfExcludedViolations =
violationsBefore - filtered.getViolations().size();
diff --git a/src/main/java/org/apache/maven/plugins/pmd/exec/PmdRequest.java b/src/main/java/org/apache/maven/plugins/pmd/exec/PmdRequest.java
index d1a80998..07036577 100644
--- a/src/main/java/org/apache/maven/plugins/pmd/exec/PmdRequest.java
+++ b/src/main/java/org/apache/maven/plugins/pmd/exec/PmdRequest.java
@@ -47,7 +47,6 @@ public class PmdRequest implements Serializable {
private String sourceEncoding;
private List files = new ArrayList<>();
- private boolean showPmdLog;
private String logLevel;
private boolean skipPmdError;
@@ -126,10 +125,6 @@ public void setFormat(String format) {
this.format = format;
}
- public void setShowPmdLog(boolean showPmdLog) {
- this.showPmdLog = showPmdLog;
- }
-
public void setLogLevel(String logLevel) {
this.logLevel = logLevel;
}
@@ -206,10 +201,6 @@ public String getFormat() {
return format;
}
- public boolean isShowPmdLog() {
- return showPmdLog;
- }
-
public String getLogLevel() {
return logLevel;
}
diff --git a/src/site/apt/examples/upgrading-PMD-at-runtime.apt.vm b/src/site/apt/examples/upgrading-PMD-at-runtime.apt.vm
index 32d8325a..c6baab3b 100644
--- a/src/site/apt/examples/upgrading-PMD-at-runtime.apt.vm
+++ b/src/site/apt/examples/upgrading-PMD-at-runtime.apt.vm
@@ -85,9 +85,11 @@ Upgrading PMD at Runtime
Here's a historical overview about the default PMD version used:
-*--------------------------------------------------------------------------------*--------------------------------------------------*
-| <> | <> |
-*--------------------------------------------------------------------------------*--------------------------------------------------*
+*--------------------------------------------------------------------------------*-----------------------------------------------------*
+| <> | <> |
+*--------------------------------------------------------------------------------*-----------------------------------------------------*
+| {{{https://maven.apache.org/plugins-archives/maven-pmd-plugin-3.22.0/}3.22.0}} | {{{https://docs.pmd-code.org/pmd-doc-7.0.0/}7.0.0}} |
+*--------------------------------------------------------------------------------*-----------------------------------------------------*
| {{{https://maven.apache.org/plugins-archives/maven-pmd-plugin-3.21.0/}3.21.0}} | {{{https://pmd.github.io/pmd-6.55.0/}6.55.0}} |
*--------------------------------------------------------------------------------*--------------------------------------------------*
| {{{https://maven.apache.org/plugins-archives/maven-pmd-plugin-3.20.0/}3.20.0}} | {{{https://pmd.github.io/pmd-6.53.0/}6.53.0}} |
diff --git a/src/site/apt/index.apt.vm b/src/site/apt/index.apt.vm
index 97fede36..1ec94a1c 100644
--- a/src/site/apt/index.apt.vm
+++ b/src/site/apt/index.apt.vm
@@ -89,10 +89,30 @@ ${project.name}
* Upgrading Notes
- <> Starting with PMD 6.0.0 and Maven PMD Plugin 3.9.0, the rules have been reorganized
- into categories, e.g. <<>>. So when upgrading to
- Maven PMD Plugin 3.9.0 you should review your plugin configuration and/or custom ruleset.
- See {{{./examples/usingRuleSets.html}Using Rule Sets}} for more information.
+** 3.22.0
+
+ * Starting with Maven PMD Plugin 3.22.0, the plugin requires PMD version 7.0.0 or higher.
+ PMD 7.0.0 switched to SLF4J and since Maven 3.1.0+ SLF4J is the default logging API.
+ Logs from PMD are now always shown and cannot be disabled at runtime after maven has started.
+ The property <<>> makes no sense anymore and is deprecated now. See
+ {{{https://maven.apache.org/maven-logging.html}Maven Logging}} for how to configure logging.
+ For disabling PMD logs, you'd need to start maven with << >>>.
+
+ * The upgrade from PMD 6 to PMD 7.0.0 is a major version change. If you use the default ruleset
+ from Maven PMD Plugin, then everything should just work. But if you use a custom ruleset, you
+ most likely need to review your ruleset and migrate it to PMD 7. Rules might have been renamed or
+ replaced. See {{{https://docs.pmd-code.org/latest/pmd_release_notes_pmd7.html}Detailed Release Notes for PMD 7}}
+ and {{{https://docs.pmd-code.org/latest/pmd_userdocs_migrating_to_pmd7.html}Migration Guide for PMD 7}}.
+
+ * If you currently override the dependency to PMD ({{{./examples/upgrading-PMD-at-runtime.html}Upgrading PMD at Runtime}})
+ make sure to upgrade PMD as well to 7.0.0 or later when upgrading the Maven PMD Plugin.
+
+** 3.9.0
+
+ * Starting with PMD 6.0.0 and Maven PMD Plugin 3.9.0, the rules have been reorganized
+ into categories, e.g. <<>>. So when upgrading to
+ Maven PMD Plugin 3.9.0 you should review your plugin configuration and/or custom ruleset.
+ See {{{./examples/usingRuleSets.html}Using Rule Sets}} for more information.
* Examples
diff --git a/src/test/java/org/apache/maven/plugins/pmd/PmdReportTest.java b/src/test/java/org/apache/maven/plugins/pmd/PmdReportTest.java
index b8ec9c33..478e5ea9 100644
--- a/src/test/java/org/apache/maven/plugins/pmd/PmdReportTest.java
+++ b/src/test/java/org/apache/maven/plugins/pmd/PmdReportTest.java
@@ -216,9 +216,9 @@ public void testFileURL() throws Exception {
.withHeader("Content-Type", "text/xml")
.withBody(sonarRuleset)));
- URL url = getClass().getClassLoader().getResource("rulesets/java/basic.xml");
- URL url2 = getClass().getClassLoader().getResource("rulesets/java/unusedcode.xml");
- URL url3 = getClass().getClassLoader().getResource("rulesets/java/imports.xml");
+ URL url = getClass().getClassLoader().getResource("category/java/bestpractices.xml");
+ URL url2 = getClass().getClassLoader().getResource("category/java/codestyle.xml");
+ URL url3 = getClass().getClassLoader().getResource("category/java/errorprone.xml");
mojo.setRulesets(new String[] {url.toString(), url2.toString(), url3.toString(), sonarExportRulesetUrl});
File generatedReport = generateReport(mojo, testPom);
@@ -229,16 +229,16 @@ public void testFileURL() throws Exception {
assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));
// the resolved and extracted rulesets
- generatedFile =
- new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/001-basic.xml");
+ generatedFile = new File(
+ getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/001-bestpractices.xml");
assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));
generatedFile =
- new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/002-unusedcode.xml");
+ new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/002-codestyle.xml");
assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));
generatedFile =
- new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/003-imports.xml");
+ new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/003-errorprone.xml");
assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));
generatedFile = new File(
@@ -424,7 +424,8 @@ public void testSuppressMarkerConfiguration() throws Exception {
// check that there is no violation reported for "unusedVar2" - as it is suppressed
assertFalse(str.contains("Avoid unused private fields such as 'unusedVar2'.\n