Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions src/main/java/org/apache/maven/plugins/pmd/PmdReport.java
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,19 @@ public class PmdReport extends AbstractPmdReport {
@Parameter(property = "pmd.rulesetsTargetDirectory", defaultValue = "${project.build.directory}/pmd/rulesets")
private File rulesetsTargetDirectory;

/**
* Controls the number of threads used by PMD Analysis for the given goal.
* This can be an integer, or a float (or int) followed by the letter `C`, eg `0.5C` or `1C`.
* In the latter case, the float will be multiplied by the number of cores of the host machine, and rounded down to an integer.
* If the specified number of threads is zero, then PMD will use the main thread for everything. If it is `n` > 0,
* PMD will spawn `n` separate analysis threads besides the main thread.
* The default behaviour is deferred to PMD and is currently 1C i.e. one thread per core on the host machine.
*
* @since 3.28.1
*/
@Parameter(property = "pmd.executionThreads")
private String executionThreads;

/**
* Used to locate configured rulesets. The rulesets could be on the plugin
* classpath or in the local project file system.
Expand Down Expand Up @@ -256,13 +269,15 @@ public PmdReport(
/**
* {@inheritDoc}
*/
@Override
public String getName(Locale locale) {
return getI18nString(locale, "name");
}

/**
* {@inheritDoc}
*/
@Override
public String getDescription(Locale locale) {
return getI18nString(locale, "description");
}
Expand Down Expand Up @@ -371,11 +386,41 @@ private void executePmd() throws MavenReportException {
request.setIncludeXmlInReports(includeXmlInReports);
request.setReportOutputDirectory(getReportOutputDirectory().getAbsolutePath());
request.setJdkToolchain(getJdkToolchain());
if (executionThreads != null) {
request.setExecutionThreads(numThreadsConverter(executionThreads));
}

getLog().info("PMD version: " + AbstractPmdReport.getPmdVersion());
pmdResult = serviceExecutor.execute(request);
}

/**
* Essentially per org.apache.maven.cli.MavenCli.calculateDegreeOfConcurrency(String).
* @return the (integer) number of threads, where a suffix of C means that a multiple of available cores is calculated.
*/
private int numThreadsConverter(String executionThreadsString) {
boolean isCoreMultiplied = executionThreadsString.endsWith("C");
if (isCoreMultiplied) {
executionThreadsString =
executionThreadsString.substring(0, executionThreadsString.length() - 1); // remove the C
try {
float f = Float.parseFloat(executionThreadsString);
if (f <= 0.0f) {
throw new IllegalArgumentException(
"Invalid threads core multiplier value: '" + f + "C'. Value must be positive.");
}
return (int) (f * Runtime.getRuntime().availableProcessors());
} catch (NumberFormatException e) {
throw new IllegalArgumentException("'" + executionThreadsString + "' is not a float or integer");
}
}
try {
return Integer.parseInt(executionThreadsString);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("'" + executionThreadsString + "' is not an integer");
}
}

/**
* Resolves the configured rulesets and copies them as files into the {@link #rulesetsTargetDirectory}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ public PmdResult run() throws MavenReportException {

configuration.setRuleSets(request.getRulesets());
configuration.setMinimumPriority(RulePriority.valueOf(request.getMinimumPriority()));
if (request.getExecutionThreads() != null) {
configuration.setThreads(request.getExecutionThreads());
}
if (request.getBenchmarkOutputLocation() != null) {
TimeTracker.startGlobalTracking();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public class PmdRequest implements Serializable {
private String benchmarkOutputLocation;
private boolean includeXmlInReports;
private String reportOutputDirectory;
private Integer executionThreads;

/**
* Configure language and language version.
Expand Down Expand Up @@ -225,4 +226,12 @@ public String getReportOutputDirectory() {
public String getExcludeFromFailureFile() {
return excludeFromFailureFile;
}

public Integer getExecutionThreads() {
return executionThreads;
}

public void setExecutionThreads(Integer executionThreads) {
this.executionThreads = executionThreads;
}
}