You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by gn...@apache.org on 2022/11/19 15:56:31 UTC
[maven-mvnd] branch master updated: Switch to maven 4.0.0-alpha-2 (#718)
This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-mvnd.git
The following commit(s) were added to refs/heads/master by this push:
new 895381b Switch to maven 4.0.0-alpha-2 (#718)
895381b is described below
commit 895381b43fbfa11d753af99c2b07f7d525083a2d
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Sat Nov 19 16:56:26 2022 +0100
Switch to maven 4.0.0-alpha-2 (#718)
---
.../java/org/apache/maven/cli/DaemonMavenCli.java | 477 +++++++++++----------
.../maven/project/CachingProjectBuilder.java | 192 ++++-----
.../apache/maven/project/SnapshotModelCache.java | 4 +-
.../mvnd/execution/BuildResumptionAnalyzer.java | 52 ---
.../mvnd/execution/BuildResumptionData.java | 60 ---
.../execution/BuildResumptionDataRepository.java | 72 ----
.../BuildResumptionPersistenceException.java | 46 --
.../execution/DefaultBuildResumptionAnalyzer.java | 85 ----
.../DefaultBuildResumptionDataRepository.java | 150 -------
.../mvnd/plugin/CachingPluginVersionResolver.java | 11 +
.../mvnd/plugin/CliMavenPluginManager.java | 36 +-
.../main/resources/META-INF/maven/extension.xml | 5 +
dist/src/main/provisio/maven-distro.xml | 8 +-
.../org/mvndaemon/mvnd/it/InteractiveTest.java | 2 +
.../mvnd/it/NewManagedModuleNativeIT.java | 4 +
pom.xml | 11 +-
16 files changed, 381 insertions(+), 834 deletions(-)
diff --git a/daemon/src/main/java/org/apache/maven/cli/DaemonMavenCli.java b/daemon/src/main/java/org/apache/maven/cli/DaemonMavenCli.java
index 5d23c9a..e088316 100644
--- a/daemon/src/main/java/org/apache/maven/cli/DaemonMavenCli.java
+++ b/daemon/src/main/java/org/apache/maven/cli/DaemonMavenCli.java
@@ -24,8 +24,6 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -37,7 +35,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
-import java.util.StringTokenizer;
+import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -45,6 +43,7 @@ import java.util.stream.Stream;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.ParseException;
+import org.apache.commons.lang3.math.NumberUtils;
import org.apache.maven.InternalErrorException;
import org.apache.maven.Maven;
import org.apache.maven.building.FileSource;
@@ -61,10 +60,7 @@ import org.apache.maven.eventspy.internal.EventSpyDispatcher;
import org.apache.maven.exception.DefaultExceptionHandler;
import org.apache.maven.exception.ExceptionHandler;
import org.apache.maven.exception.ExceptionSummary;
-import org.apache.maven.execution.MavenExecutionRequest;
-import org.apache.maven.execution.MavenExecutionRequestPopulationException;
-import org.apache.maven.execution.MavenExecutionRequestPopulator;
-import org.apache.maven.execution.MavenExecutionResult;
+import org.apache.maven.execution.*;
import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule;
import org.apache.maven.extension.internal.CoreExports;
import org.apache.maven.extension.internal.CoreExtensionEntry;
@@ -101,9 +97,6 @@ import org.mvndaemon.mvnd.cache.invalidating.InvalidatingProjectArtifactsCache;
import org.mvndaemon.mvnd.cli.EnvHelper;
import org.mvndaemon.mvnd.common.Environment;
import org.mvndaemon.mvnd.common.Os;
-import org.mvndaemon.mvnd.execution.BuildResumptionPersistenceException;
-import org.mvndaemon.mvnd.execution.DefaultBuildResumptionAnalyzer;
-import org.mvndaemon.mvnd.execution.DefaultBuildResumptionDataRepository;
import org.mvndaemon.mvnd.logging.internal.Slf4jLoggerManager;
import org.mvndaemon.mvnd.logging.smart.BuildEventListener;
import org.mvndaemon.mvnd.logging.smart.LoggingExecutionListener;
@@ -177,7 +170,9 @@ public class DaemonMavenCli {
private final LoggingExecutionListener executionListener;
- /** Non-volatile, assuming that it is accessed only from the main thread */
+ /**
+ * Non-volatile, assuming that it is accessed only from the main thread
+ */
private BuildEventListener buildEventListener = BuildEventListener.dummy();
public DaemonMavenCli() throws Exception {
@@ -354,12 +349,12 @@ public class DaemonMavenCli {
*/
void logging(CliRequest cliRequest) {
// LOG LEVEL
- cliRequest.debug = cliRequest.commandLine.hasOption(CLIManager.DEBUG);
- cliRequest.quiet = !cliRequest.debug && cliRequest.commandLine.hasOption(CLIManager.QUIET);
- cliRequest.showErrors = cliRequest.debug || cliRequest.commandLine.hasOption(CLIManager.ERRORS);
+ cliRequest.verbose = cliRequest.commandLine.hasOption(CLIManager.VERBOSE);
+ cliRequest.quiet = !cliRequest.verbose && cliRequest.commandLine.hasOption(CLIManager.QUIET);
+ cliRequest.showErrors = cliRequest.verbose || cliRequest.commandLine.hasOption(CLIManager.ERRORS);
ch.qos.logback.classic.Level level;
- if (cliRequest.debug) {
+ if (cliRequest.verbose) {
level = ch.qos.logback.classic.Level.DEBUG;
} else if (cliRequest.quiet) {
level = ch.qos.logback.classic.Level.WARN;
@@ -413,7 +408,7 @@ public class DaemonMavenCli {
}
private void version(CliRequest cliRequest) throws ExitException {
- if (cliRequest.debug || cliRequest.commandLine.hasOption(CLIManager.VERSION)) {
+ if (cliRequest.verbose || cliRequest.commandLine.hasOption(CLIManager.VERSION)) {
buildEventListener.log(CLIReportingUtils.showVersion());
if (cliRequest.commandLine.hasOption(CLIManager.VERSION)) {
throw new ExitException(0);
@@ -576,7 +571,7 @@ public class DaemonMavenCli {
properties(cliRequest);
configure(cliRequest, eventSpyDispatcher, configurationProcessors);
LoggingExecutionListener executionListener = container.lookup(LoggingExecutionListener.class);
- populateRequest(cliRequest, cliRequest.request, slf4jLogger, eventSpyDispatcher,
+ populateRequest(cliRequest, cliRequest.request, eventSpyDispatcher,
container.lookup(ModelProcessor.class), createTransferListener(cliRequest), buildEventListener,
executionListener);
executionRequestPopulator.populateDefaults(cliRequest.request);
@@ -729,18 +724,7 @@ public class DaemonMavenCli {
}
}
- boolean canResume = new DefaultBuildResumptionAnalyzer().determineBuildResumptionData(result).map(resumption -> {
- try {
- Path directory = Paths.get(request.getBaseDirectory()).resolve("target");
- new DefaultBuildResumptionDataRepository().persistResumptionData(directory, resumption);
- return true;
- } catch (BuildResumptionPersistenceException e) {
- slf4jLogger.warn("Could not persist build resumption data", e);
- }
- return false;
- }).orElse(false);
-
- if (canResume) {
+ if (result.canResume()) {
logBuildResumeHint("mvn <args> -r");
} else if (!failedProjects.isEmpty()) {
List<MavenProject> sortedProjects = result.getTopologicallySortedProjects();
@@ -763,8 +747,6 @@ public class DaemonMavenCli {
return 1;
}
} else {
- Path directory = Paths.get(request.getBaseDirectory()).resolve("target");
- new DefaultBuildResumptionDataRepository().removeResumptionData(directory);
return 0;
}
}
@@ -999,14 +981,13 @@ public class DaemonMavenCli {
}
private void populateRequest(CliRequest cliRequest) {
- populateRequest(cliRequest, cliRequest.request, slf4jLogger, eventSpyDispatcher, modelProcessor,
+ populateRequest(cliRequest, cliRequest.request, eventSpyDispatcher, modelProcessor,
createTransferListener(cliRequest), buildEventListener, executionListener);
}
- private static void populateRequest(
+ private void populateRequest(
CliRequest cliRequest,
MavenExecutionRequest request,
- Logger slf4jLogger,
EventSpyDispatcher eventSpyDispatcher,
ModelProcessor modelProcessor,
TransferListener transferListener,
@@ -1014,244 +995,285 @@ public class DaemonMavenCli {
LoggingExecutionListener executionListener) {
CommandLine commandLine = cliRequest.commandLine;
String workingDirectory = cliRequest.workingDirectory;
- boolean showErrors = cliRequest.showErrors;
-
- String[] deprecatedOptions = { "up", "npu", "cpu", "npr" };
- for (String deprecatedOption : deprecatedOptions) {
- if (commandLine.hasOption(deprecatedOption)) {
- slf4jLogger.warn("Command line option -{} is deprecated and will be removed in future Maven versions.",
- deprecatedOption);
- }
- }
-
- // ----------------------------------------------------------------------
- // Now that we have everything that we need we will fire up plexus and
- // bring the maven component to life for use.
- // ----------------------------------------------------------------------
-
- if (commandLine.hasOption(CLIManager.BATCH_MODE)) {
- request.setInteractiveMode(false);
- }
-
- boolean noSnapshotUpdates = false;
- if (commandLine.hasOption(CLIManager.SUPRESS_SNAPSHOT_UPDATES)) {
- noSnapshotUpdates = true;
- }
-
- // ----------------------------------------------------------------------
- //
- // ----------------------------------------------------------------------
-
- List<String> goals = commandLine.getArgList();
-
- boolean recursive = true;
+ boolean quiet = cliRequest.quiet;
+ boolean verbose = cliRequest.verbose;
+ request.setShowErrors(cliRequest.showErrors); // default: false
+ File baseDirectory = new File(workingDirectory, "").getAbsoluteFile();
- // this is the default behavior.
- String reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
+ disableOnPresentOption(commandLine, CLIManager.BATCH_MODE, request::setInteractiveMode);
+ enableOnPresentOption(commandLine, CLIManager.SUPPRESS_SNAPSHOT_UPDATES, request::setNoSnapshotUpdates);
+ request.setGoals(commandLine.getArgList());
+ request.setReactorFailureBehavior(determineReactorFailureBehaviour(commandLine));
+ disableOnPresentOption(commandLine, CLIManager.NON_RECURSIVE, request::setRecursive);
+ enableOnPresentOption(commandLine, CLIManager.OFFLINE, request::setOffline);
+ enableOnPresentOption(commandLine, CLIManager.UPDATE_SNAPSHOTS, request::setUpdateSnapshots);
+ request.setGlobalChecksumPolicy(determineGlobalCheckPolicy(commandLine));
+ request.setBaseDirectory(baseDirectory);
+ request.setSystemProperties(cliRequest.systemProperties);
+ request.setUserProperties(cliRequest.userProperties);
+ request.setMultiModuleProjectDirectory(cliRequest.multiModuleProjectDirectory);
+ request.setPom(determinePom(modelProcessor, commandLine, workingDirectory, baseDirectory));
+ request.setTransferListener(transferListener);
+ request.setExecutionListener(executionListener);
- if (commandLine.hasOption(CLIManager.NON_RECURSIVE)) {
- recursive = false;
- }
+ ExecutionEventLogger executionEventLogger = new ExecutionEventLogger();
+ executionListener.init(
+ eventSpyDispatcher.chainListener(executionEventLogger),
+ buildEventListener);
- if (commandLine.hasOption(CLIManager.FAIL_FAST)) {
- reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
- } else if (commandLine.hasOption(CLIManager.FAIL_AT_END)) {
- reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_AT_END;
- } else if (commandLine.hasOption(CLIManager.FAIL_NEVER)) {
- reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_NEVER;
+ if ((request.getPom() != null) && (request.getPom().getParentFile() != null)) {
+ request.setBaseDirectory(request.getPom().getParentFile());
}
- if (commandLine.hasOption(CLIManager.OFFLINE)) {
- request.setOffline(true);
- }
+ request.setResumeFrom(commandLine.getOptionValue(CLIManager.RESUME_FROM));
+ enableOnPresentOption(commandLine, CLIManager.RESUME, request::setResume);
+ request.setMakeBehavior(determineMakeBehavior(commandLine));
+ request.setCacheNotFound(true);
+ request.setCacheTransferError(false);
- boolean updateSnapshots = false;
+ performProjectActivation(commandLine, request.getProjectActivation());
+ performProfileActivation(commandLine, request.getProfileActivation());
- if (commandLine.hasOption(CLIManager.UPDATE_SNAPSHOTS)) {
- updateSnapshots = true;
+ final String localRepositoryPath = determineLocalRepositoryPath(request);
+ if (localRepositoryPath != null) {
+ request.setLocalRepositoryPath(localRepositoryPath);
}
- String globalChecksumPolicy = null;
+ //
+ // Builder, concurrency and parallelism
+ //
+ // We preserve the existing methods for builder selection which is to look for various inputs in the threading
+ // configuration. We don't have an easy way to allow a pluggable builder to provide its own configuration
+ // parameters but this is sufficient for now. Ultimately we want components like Builders to provide a way to
+ // extend the command line to accept its own configuration parameters.
+ //
+ final String threadConfiguration = commandLine.getOptionValue(CLIManager.THREADS);
- if (commandLine.hasOption(CLIManager.CHECKSUM_FAILURE_POLICY)) {
- globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_FAIL;
- } else if (commandLine.hasOption(CLIManager.CHECKSUM_WARNING_POLICY)) {
- globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_WARN;
+ if (threadConfiguration != null) {
+ int degreeOfConcurrency = calculateDegreeOfConcurrency(threadConfiguration);
+ if (degreeOfConcurrency > 1) {
+ request.setBuilderId("multithreaded");
+ request.setDegreeOfConcurrency(degreeOfConcurrency);
+ }
}
- File baseDirectory = new File(workingDirectory, "").getAbsoluteFile();
-
- // ----------------------------------------------------------------------
- // Profile Activation
- // ----------------------------------------------------------------------
-
- List<String> activeProfiles = new ArrayList<>();
-
- List<String> inactiveProfiles = new ArrayList<>();
+ //
+ // Allow the builder to be overridden by the user if requested. The builders are now pluggable.
+ //
+ request.setBuilderId(commandLine.getOptionValue(CLIManager.BUILDER, request.getBuilderId()));
+ }
- if (commandLine.hasOption(CLIManager.ACTIVATE_PROFILES)) {
- String[] profileOptionValues = commandLine.getOptionValues(CLIManager.ACTIVATE_PROFILES);
- if (profileOptionValues != null) {
- for (String profileOptionValue : profileOptionValues) {
- StringTokenizer profileTokens = new StringTokenizer(profileOptionValue, ",");
-
- while (profileTokens.hasMoreTokens()) {
- String profileAction = profileTokens.nextToken().trim();
-
- if (profileAction.startsWith("-") || profileAction.startsWith("!")) {
- inactiveProfiles.add(profileAction.substring(1));
- } else if (profileAction.startsWith("+")) {
- activeProfiles.add(profileAction.substring(1));
- } else {
- activeProfiles.add(profileAction);
- }
- }
- }
- }
+ private String determineLocalRepositoryPath(final MavenExecutionRequest request) {
+ String userDefinedLocalRepo = request.getUserProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY);
+ if (userDefinedLocalRepo != null) {
+ return userDefinedLocalRepo;
}
- ExecutionEventLogger executionEventLogger = new ExecutionEventLogger();
- executionListener.init(
- eventSpyDispatcher.chainListener(executionEventLogger),
- buildEventListener);
+ return request.getSystemProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY);
+ }
+ private File determinePom(ModelProcessor modelProcessor, final CommandLine commandLine, final String workingDirectory,
+ final File baseDirectory) {
String alternatePomFile = null;
if (commandLine.hasOption(CLIManager.ALTERNATE_POM_FILE)) {
alternatePomFile = commandLine.getOptionValue(CLIManager.ALTERNATE_POM_FILE);
}
- request.setBaseDirectory(baseDirectory)
- .setGoals(goals)
- .setSystemProperties(cliRequest.systemProperties)
- .setUserProperties(cliRequest.userProperties)
- .setReactorFailureBehavior(reactorFailureBehaviour) // default: fail fast
- .setRecursive(recursive) // default: true
- .setShowErrors(showErrors) // default: false
- .addActiveProfiles(activeProfiles) // optional
- .addInactiveProfiles(inactiveProfiles) // optional
- .setExecutionListener(executionListener)
- .setTransferListener(transferListener) // default: batch mode which goes along with interactive
- .setUpdateSnapshots(updateSnapshots) // default: false
- .setNoSnapshotUpdates(noSnapshotUpdates) // default: false
- .setGlobalChecksumPolicy(globalChecksumPolicy) // default: warn
- .setMultiModuleProjectDirectory(cliRequest.getMultiModuleProjectDirectory());
-
if (alternatePomFile != null) {
File pom = resolveFile(new File(alternatePomFile), workingDirectory);
if (pom.isDirectory()) {
pom = new File(pom, "pom.xml");
}
- request.setPom(pom);
+ return pom;
} else if (modelProcessor != null) {
File pom = modelProcessor.locatePom(baseDirectory);
if (pom.isFile()) {
- request.setPom(pom);
+ return pom;
}
}
- if ((request.getPom() != null) && (request.getPom().getParentFile() != null)) {
- request.setBaseDirectory(request.getPom().getParentFile());
- }
+ return null;
+ }
- if (commandLine.hasOption(RESUME)) {
- new DefaultBuildResumptionDataRepository()
- .applyResumptionData(request, Paths.get(request.getBaseDirectory()).resolve("target"));
- }
+ // Visible for testing
+ static void performProjectActivation(final CommandLine commandLine, final ProjectActivation projectActivation) {
+ if (commandLine.hasOption(CLIManager.PROJECT_LIST)) {
+ final String[] optionValues = commandLine.getOptionValues(CLIManager.PROJECT_LIST);
- if (commandLine.hasOption(CLIManager.RESUME_FROM)) {
- request.setResumeFrom(commandLine.getOptionValue(CLIManager.RESUME_FROM));
- }
+ if (optionValues == null || optionValues.length == 0) {
+ return;
+ }
- if (commandLine.hasOption(CLIManager.PROJECT_LIST)) {
- String[] projectOptionValues = commandLine.getOptionValues(CLIManager.PROJECT_LIST);
+ for (final String optionValue : optionValues) {
+ for (String token : optionValue.split(",")) {
+ String selector = token.trim();
+ boolean active = true;
+ if (selector.charAt(0) == '-' || selector.charAt(0) == '!') {
+ active = false;
+ selector = selector.substring(1);
+ } else if (token.charAt(0) == '+') {
+ selector = selector.substring(1);
+ }
- List<String> inclProjects = new ArrayList<>();
- List<String> exclProjects = new ArrayList<>();
+ boolean optional = selector.charAt(0) == '?';
+ selector = selector.substring(optional ? 1 : 0);
- if (projectOptionValues != null) {
- for (String projectOptionValue : projectOptionValues) {
- StringTokenizer projectTokens = new StringTokenizer(projectOptionValue, ",");
+ projectActivation.addProjectActivation(selector, active, optional);
+ }
+ }
+ }
+ }
- while (projectTokens.hasMoreTokens()) {
- String projectAction = projectTokens.nextToken().trim();
+ // Visible for testing
+ static void performProfileActivation(final CommandLine commandLine, final ProfileActivation profileActivation) {
+ if (commandLine.hasOption(CLIManager.ACTIVATE_PROFILES)) {
+ final String[] optionValues = commandLine.getOptionValues(CLIManager.ACTIVATE_PROFILES);
+
+ if (optionValues == null || optionValues.length == 0) {
+ return;
+ }
- if (projectAction.startsWith("-") || projectAction.startsWith("!")) {
- exclProjects.add(projectAction.substring(1));
- } else if (projectAction.startsWith("+")) {
- inclProjects.add(projectAction.substring(1));
- } else {
- inclProjects.add(projectAction);
- }
+ for (final String optionValue : optionValues) {
+ for (String token : optionValue.split(",")) {
+ String profileId = token.trim();
+ boolean active = true;
+ if (profileId.charAt(0) == '-' || profileId.charAt(0) == '!') {
+ active = false;
+ profileId = profileId.substring(1);
+ } else if (token.charAt(0) == '+') {
+ profileId = profileId.substring(1);
}
+
+ boolean optional = profileId.charAt(0) == '?';
+ profileId = profileId.substring(optional ? 1 : 0);
+
+ profileActivation.addProfileActivation(profileId, active, optional);
}
}
-
- request.setSelectedProjects(inclProjects);
- request.setExcludedProjects(exclProjects);
}
+ }
- if (commandLine.hasOption(CLIManager.ALSO_MAKE) && !commandLine.hasOption(
- CLIManager.ALSO_MAKE_DEPENDENTS)) {
- request.setMakeBehavior(MavenExecutionRequest.REACTOR_MAKE_UPSTREAM);
- } else if (!commandLine.hasOption(CLIManager.ALSO_MAKE) && commandLine.hasOption(
- CLIManager.ALSO_MAKE_DEPENDENTS)) {
- request.setMakeBehavior(MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM);
- } else if (commandLine.hasOption(CLIManager.ALSO_MAKE) && commandLine.hasOption(
- CLIManager.ALSO_MAKE_DEPENDENTS)) {
- request.setMakeBehavior(MavenExecutionRequest.REACTOR_MAKE_BOTH);
+ private ExecutionListener determineExecutionListener(EventSpyDispatcher eventSpyDispatcher) {
+ ExecutionListener executionListener = new ExecutionEventLogger();
+ if (eventSpyDispatcher != null) {
+ return eventSpyDispatcher.chainListener(executionListener);
+ } else {
+ return executionListener;
}
+ }
- String localRepoProperty = request.getUserProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY);
-
- if (localRepoProperty == null) {
- localRepoProperty = request.getSystemProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY);
+ private String determineReactorFailureBehaviour(final CommandLine commandLine) {
+ if (commandLine.hasOption(CLIManager.FAIL_FAST)) {
+ return MavenExecutionRequest.REACTOR_FAIL_FAST;
+ } else if (commandLine.hasOption(CLIManager.FAIL_AT_END)) {
+ return MavenExecutionRequest.REACTOR_FAIL_AT_END;
+ } else if (commandLine.hasOption(CLIManager.FAIL_NEVER)) {
+ return MavenExecutionRequest.REACTOR_FAIL_NEVER;
+ } else {
+ // this is the default behavior.
+ return MavenExecutionRequest.REACTOR_FAIL_FAST;
}
+ }
- if (localRepoProperty != null) {
- request.setLocalRepositoryPath(localRepoProperty);
+ private String determineMakeBehavior(final CommandLine cl) {
+ if (cl.hasOption(CLIManager.ALSO_MAKE) && !cl.hasOption(CLIManager.ALSO_MAKE_DEPENDENTS)) {
+ return MavenExecutionRequest.REACTOR_MAKE_UPSTREAM;
+ } else if (!cl.hasOption(CLIManager.ALSO_MAKE) && cl.hasOption(CLIManager.ALSO_MAKE_DEPENDENTS)) {
+ return MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM;
+ } else if (cl.hasOption(CLIManager.ALSO_MAKE) && cl.hasOption(CLIManager.ALSO_MAKE_DEPENDENTS)) {
+ return MavenExecutionRequest.REACTOR_MAKE_BOTH;
+ } else {
+ return null;
}
+ }
- request.setCacheNotFound(true);
- request.setCacheTransferError(false);
+ private String determineGlobalCheckPolicy(final CommandLine commandLine) {
+ if (commandLine.hasOption(CLIManager.CHECKSUM_FAILURE_POLICY)) {
+ return MavenExecutionRequest.CHECKSUM_POLICY_FAIL;
+ } else if (commandLine.hasOption(CLIManager.CHECKSUM_WARNING_POLICY)) {
+ return MavenExecutionRequest.CHECKSUM_POLICY_WARN;
+ } else {
+ return null;
+ }
+ }
- //
- // Builder, concurrency and parallelism
- //
- // We preserve the existing methods for builder selection which is to look for various inputs in the threading
- // configuration. We don't have an easy way to allow a pluggable builder to provide its own configuration
- // parameters but this is sufficient for now. Ultimately we want components like Builders to provide a way to
- // extend the command line to accept its own configuration parameters.
- //
- final String threadConfiguration = commandLine.hasOption(CLIManager.THREADS)
- ? commandLine.getOptionValue(CLIManager.THREADS)
- : null;
+ private void disableOnPresentOption(final CommandLine commandLine,
+ final String option,
+ final Consumer<Boolean> setting) {
+ if (commandLine.hasOption(option)) {
+ setting.accept(false);
+ }
+ }
- if (threadConfiguration != null) {
- //
- // Default to the standard multithreaded builder
- //
- request.setBuilderId("multithreaded");
+ private void disableOnPresentOption(final CommandLine commandLine,
+ final char option,
+ final Consumer<Boolean> setting) {
+ disableOnPresentOption(commandLine, String.valueOf(option), setting);
+ }
- if (threadConfiguration.contains("C")) {
- request.setDegreeOfConcurrency(calculateDegreeOfConcurrencyWithCoreMultiplier(threadConfiguration));
- } else {
- request.setDegreeOfConcurrency(Integer.parseInt(threadConfiguration));
- }
+ private void enableOnPresentOption(final CommandLine commandLine,
+ final String option,
+ final Consumer<Boolean> setting) {
+ if (commandLine.hasOption(option)) {
+ setting.accept(true);
}
+ }
- //
- // Allow the builder to be overridden by the user if requested. The builders are now pluggable.
- //
- if (commandLine.hasOption(CLIManager.BUILDER)) {
- request.setBuilderId(commandLine.getOptionValue(CLIManager.BUILDER));
+ private void enableOnPresentOption(final CommandLine commandLine,
+ final char option,
+ final Consumer<Boolean> setting) {
+ enableOnPresentOption(commandLine, String.valueOf(option), setting);
+ }
+
+ private void enableOnAbsentOption(final CommandLine commandLine,
+ final char option,
+ final Consumer<Boolean> setting) {
+ if (!commandLine.hasOption(option)) {
+ setting.accept(true);
}
}
- static int calculateDegreeOfConcurrencyWithCoreMultiplier(String threadConfiguration) {
- int procs = Runtime.getRuntime().availableProcessors();
- return (int) (Float.parseFloat(threadConfiguration.replace("C", "")) * procs);
+ int calculateDegreeOfConcurrency(String threadConfiguration) {
+ if (threadConfiguration.endsWith("C")) {
+ threadConfiguration = threadConfiguration.substring(0, threadConfiguration.length() - 1);
+
+ if (!NumberUtils.isParsable(threadConfiguration)) {
+ throw new IllegalArgumentException("Invalid threads core multiplier value: '" + threadConfiguration
+ + "C'. Supported are int and float values ending with C.");
+ }
+
+ float coreMultiplier = Float.parseFloat(threadConfiguration);
+
+ if (coreMultiplier <= 0.0f) {
+ throw new IllegalArgumentException("Invalid threads core multiplier value: '" + threadConfiguration
+ + "C'. Value must be positive.");
+ }
+
+ int procs = Runtime.getRuntime().availableProcessors();
+ int threads = (int) (coreMultiplier * procs);
+ return threads == 0 ? 1 : threads;
+ } else {
+ if (!NumberUtils.isParsable(threadConfiguration)) {
+ throw new IllegalArgumentException("Invalid threads value: '" + threadConfiguration
+ + "'. Supported are int values.");
+ }
+
+ try {
+ int threads = Integer.parseInt(threadConfiguration);
+
+ if (threads <= 0) {
+ throw new IllegalArgumentException("Invalid threads value: '" + threadConfiguration
+ + "'. Value must be positive.");
+ }
+
+ return threads;
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid threads value: '" + threadConfiguration
+ + "'. Supported are integer values.");
+ }
+ }
}
static File resolveFile(File file, String workingDirectory) {
@@ -1280,15 +1302,10 @@ public class DaemonMavenCli {
// are most dominant.
// ----------------------------------------------------------------------
- if (commandLine.hasOption(CLIManager.SET_SYSTEM_PROPERTY)) {
- String[] defStrs = commandLine.getOptionValues(CLIManager.SET_SYSTEM_PROPERTY);
-
- if (defStrs != null) {
- for (String defStr : defStrs) {
- setCliProperty(defStr, userProperties);
- }
- }
- }
+ final Properties userSpecifiedProperties = commandLine.getOptionProperties(
+ String.valueOf(CLIManager.SET_SYSTEM_PROPERTY));
+ userSpecifiedProperties.forEach(
+ (prop, value) -> setCliProperty((String) prop, (String) value, userProperties));
SystemProperties.addSystemProperties(systemProperties);
@@ -1316,23 +1333,7 @@ public class DaemonMavenCli {
}
}
- private static void setCliProperty(String property, Properties properties) {
- String name;
-
- String value;
-
- int i = property.indexOf('=');
-
- if (i <= 0) {
- name = property.trim();
-
- value = "true";
- } else {
- name = property.substring(0, i).trim();
-
- value = property.substring(i + 1);
- }
-
+ private static void setCliProperty(String name, String value, Properties properties) {
properties.setProperty(name, value);
// ----------------------------------------------------------------------
diff --git a/daemon/src/main/java/org/apache/maven/project/CachingProjectBuilder.java b/daemon/src/main/java/org/apache/maven/project/CachingProjectBuilder.java
index 9a919db..0dfe755 100644
--- a/daemon/src/main/java/org/apache/maven/project/CachingProjectBuilder.java
+++ b/daemon/src/main/java/org/apache/maven/project/CachingProjectBuilder.java
@@ -31,6 +31,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
@@ -41,6 +42,7 @@ import org.apache.maven.artifact.InvalidRepositoryException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.LegacyLocalRepositoryManager;
import org.apache.maven.bridge.MavenRepositorySystem;
+import org.apache.maven.feature.Features;
import org.apache.maven.model.Build;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
@@ -50,6 +52,7 @@ import org.apache.maven.model.Model;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.Profile;
import org.apache.maven.model.ReportPlugin;
+import org.apache.maven.model.building.ArtifactModelSource;
import org.apache.maven.model.building.DefaultModelBuildingRequest;
import org.apache.maven.model.building.DefaultModelProblem;
import org.apache.maven.model.building.FileModelSource;
@@ -62,11 +65,15 @@ import org.apache.maven.model.building.ModelProblem;
import org.apache.maven.model.building.ModelProcessor;
import org.apache.maven.model.building.ModelSource;
import org.apache.maven.model.building.StringModelSource;
+import org.apache.maven.model.building.TransformerContext;
+import org.apache.maven.model.building.TransformerContextBuilder;
import org.apache.maven.model.resolution.ModelResolver;
import org.apache.maven.repository.internal.ArtifactDescriptorUtils;
+import org.apache.maven.repository.internal.DefaultModelCache;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.Os;
import org.codehaus.plexus.util.StringUtils;
+import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.RequestTrace;
import org.eclipse.aether.impl.RemoteRepositoryManager;
@@ -76,17 +83,12 @@ import org.eclipse.aether.repository.WorkspaceRepository;
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.sisu.Priority;
-import org.eclipse.sisu.Typed;
/**
- * DefaultProjectBuilder
- *
- * File origin:
- * https://github.com/apache/maven/blob/maven-3.6.2/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
+ * CachingProjectBuilder
*/
@Named
@Singleton
-@Typed(ProjectBuilder.class)
@Priority(10)
public class CachingProjectBuilder
implements ProjectBuilder {
@@ -115,10 +117,7 @@ public class CachingProjectBuilder
@Inject
private ProjectDependenciesResolver dependencyResolver;
- private final ModelCache modelCache = new ReactorModelCache();
-
- public CachingProjectBuilder() {
- }
+ private final ModelCache modelCache = DefaultModelCache.newInstance(new DefaultRepositorySystemSession());
// ----------------------------------------------------------------------
// MavenProjectBuilder Implementation
@@ -128,14 +127,14 @@ public class CachingProjectBuilder
public ProjectBuildingResult build(File pomFile, ProjectBuildingRequest request)
throws ProjectBuildingException {
return build(pomFile, new FileModelSource(pomFile),
- new InternalConfig(request, null, new SnapshotModelCache(getModelCache())));
+ new InternalConfig(request, null, null));
}
@Override
public ProjectBuildingResult build(ModelSource modelSource, ProjectBuildingRequest request)
throws ProjectBuildingException {
return build(null, modelSource,
- new InternalConfig(request, null, new SnapshotModelCache(getModelCache())));
+ new InternalConfig(request, null, null));
}
private ProjectBuildingResult build(File pomFile, ModelSource modelSource, InternalConfig config)
@@ -170,8 +169,7 @@ public class CachingProjectBuilder
} catch (ModelBuildingException e) {
result = e.getResult();
if (result == null || result.getEffectiveModel() == null) {
- throw (ProjectBuildingException) new ProjectBuildingException(e.getModelId(), e.getMessage(), pomFile)
- .initCause(e);
+ throw new ProjectBuildingException(e.getModelId(), e.getMessage(), pomFile, e);
}
// validation error, continue project building and delay failing to help IDEs
error = e;
@@ -179,8 +177,8 @@ public class CachingProjectBuilder
modelProblems = result.getProblems();
- initProject(project, Collections.<String, MavenProject> emptyMap(), true,
- result, new HashMap<File, Boolean>(), projectBuildingRequest);
+ initProject(project, Collections.emptyMap(), true,
+ result, new HashMap<>(), projectBuildingRequest);
} else if (projectBuildingRequest.isResolveDependencies()) {
projectBuildingHelper.selectProjectRealm(project);
}
@@ -235,13 +233,7 @@ public class CachingProjectBuilder
}
private List<String> getProfileIds(List<Profile> profiles) {
- List<String> ids = new ArrayList<>(profiles.size());
-
- for (Profile profile : profiles) {
- ids.add(profile.getId());
- }
-
- return ids;
+ return profiles.stream().map(Profile::getId).collect(Collectors.toList());
}
private ModelBuildingRequest getModelBuildingRequest(InternalConfig config) {
@@ -264,7 +256,11 @@ public class CachingProjectBuilder
request.setUserProperties(configuration.getUserProperties());
request.setBuildStartTime(configuration.getBuildStartTime());
request.setModelResolver(resolver);
- request.setModelCache(config.modelCache);
+ // this is a hint that we want to build 1 file, so don't cache. See MNG-7063
+ if (config.modelPool != null) {
+ request.setModelCache(new SnapshotModelCache(modelCache, DefaultModelCache.newInstance(config.session)));
+ }
+ request.setTransformerContextBuilder(config.transformerContextBuilder);
return request;
}
@@ -281,7 +277,7 @@ public class CachingProjectBuilder
org.eclipse.aether.artifact.Artifact pomArtifact = RepositoryUtils.toArtifact(artifact);
pomArtifact = ArtifactDescriptorUtils.toPomArtifact(pomArtifact);
- InternalConfig config = new InternalConfig(request, null, new SnapshotModelCache(getModelCache()));
+ InternalConfig config = new InternalConfig(request, null, null);
boolean localProject;
@@ -309,7 +305,13 @@ public class CachingProjectBuilder
artifact.setResolved(true);
}
- return build(localProject ? pomFile : null, new FileModelSource(pomFile), config);
+ if (localProject) {
+ return build(pomFile, new FileModelSource(pomFile), config);
+ } else {
+ return build(null, new ArtifactModelSource(pomFile, artifact.getGroupId(), artifact.getArtifactId(),
+ artifact.getVersion()),
+ config);
+ }
}
private ModelSource createStubModelSource(Artifact artifact) {
@@ -334,26 +336,32 @@ public class CachingProjectBuilder
List<InterimResult> interimResults = new ArrayList<>();
- ReactorModelPool modelPool = new ReactorModelPool();
+ ReactorModelPool.Builder poolBuilder = new ReactorModelPool.Builder();
+ final ReactorModelPool modelPool = poolBuilder.build();
- InternalConfig config = new InternalConfig(request, modelPool, new SnapshotModelCache(getModelCache()));
+ InternalConfig config = new InternalConfig(request, modelPool, modelBuilder.newTransformerContextBuilder());
- Map<String, MavenProject> projectIndex = new HashMap<>(256);
+ Map<File, MavenProject> projectIndex = new HashMap<>(256);
- boolean noErrors = build(results, interimResults, projectIndex, pomFiles, new LinkedHashSet<File>(), true, recursive,
- config);
-
- populateReactorModelPool(modelPool, interimResults);
+ // phase 1: get file Models from the reactor.
+ boolean noErrors = build(results, interimResults, projectIndex, pomFiles, new LinkedHashSet<>(), true, recursive,
+ config, poolBuilder);
ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
try {
- noErrors = build(results, new ArrayList<MavenProject>(), projectIndex, interimResults, request,
- new HashMap<File, Boolean>(), config.session) && noErrors;
+ // Phase 2: get effective models from the reactor
+ noErrors = build(results, new ArrayList<>(), projectIndex, interimResults, request,
+ new HashMap<>(), config.session) && noErrors;
} finally {
Thread.currentThread().setContextClassLoader(oldContextClassLoader);
}
+ if (Features.buildConsumer(request.getUserProperties()).isActive()) {
+ request.getRepositorySession().getData().set(TransformerContext.KEY,
+ config.transformerContextBuilder.build());
+ }
+
if (!noErrors) {
throw new ProjectBuildingException(results);
}
@@ -363,14 +371,16 @@ public class CachingProjectBuilder
@SuppressWarnings("checkstyle:parameternumber")
private boolean build(List<ProjectBuildingResult> results, List<InterimResult> interimResults,
- Map<String, MavenProject> projectIndex, List<File> pomFiles, Set<File> aggregatorFiles,
- boolean isRoot, boolean recursive, InternalConfig config) {
+ Map<File, MavenProject> projectIndex, List<File> pomFiles, Set<File> aggregatorFiles,
+ boolean root, boolean recursive, InternalConfig config,
+ ReactorModelPool.Builder poolBuilder) {
boolean noErrors = true;
for (File pomFile : pomFiles) {
aggregatorFiles.add(pomFile);
- if (!build(results, interimResults, projectIndex, pomFile, aggregatorFiles, isRoot, recursive, config)) {
+ if (!build(results, interimResults, projectIndex, pomFile, aggregatorFiles, root, recursive, config,
+ poolBuilder)) {
noErrors = false;
}
@@ -382,18 +392,18 @@ public class CachingProjectBuilder
@SuppressWarnings("checkstyle:parameternumber")
private boolean build(List<ProjectBuildingResult> results, List<InterimResult> interimResults,
- Map<String, MavenProject> projectIndex, File pomFile, Set<File> aggregatorFiles,
- boolean isRoot, boolean recursive, InternalConfig config) {
+ Map<File, MavenProject> projectIndex, File pomFile, Set<File> aggregatorFiles,
+ boolean isRoot, boolean recursive, InternalConfig config,
+ ReactorModelPool.Builder poolBuilder) {
boolean noErrors = true;
- ModelBuildingRequest request = getModelBuildingRequest(config);
-
MavenProject project = new MavenProject();
project.setFile(pomFile);
- request.setPomFile(pomFile);
- request.setTwoPhaseBuilding(true);
- request.setLocationTracking(true);
+ ModelBuildingRequest request = getModelBuildingRequest(config)
+ .setPomFile(pomFile)
+ .setTwoPhaseBuilding(true)
+ .setLocationTracking(true);
DefaultModelBuildingListener listener = new DefaultModelBuildingListener(project, projectBuildingHelper,
config.request);
@@ -404,7 +414,7 @@ public class CachingProjectBuilder
result = modelBuilder.build(request);
} catch (ModelBuildingException e) {
result = e.getResult();
- if (result == null || result.getEffectiveModel() == null) {
+ if (result == null || result.getFileModel() == null) {
results.add(new DefaultProjectBuildingResult(e.getModelId(), pomFile, e.getProblems()));
return false;
@@ -414,25 +424,16 @@ public class CachingProjectBuilder
noErrors = false;
}
- Model model = result.getEffectiveModel();
- try {
- // first pass: build without building parent.
- initProject(project, projectIndex, false, result, new HashMap<File, Boolean>(0), config.request);
- } catch (InvalidArtifactRTException iarte) {
- result.getProblems().add(new DefaultModelProblem(null, ModelProblem.Severity.ERROR, null, model, -1, -1,
- iarte));
- }
+ Model model = result.getFileModel().clone();
- projectIndex.put(result.getModelIds().get(0), project);
+ poolBuilder.put(model.getPomFile().toPath(), model);
InterimResult interimResult = new InterimResult(pomFile, request, result, listener, isRoot);
interimResults.add(interimResult);
- if (recursive && !model.getModules().isEmpty()) {
+ if (recursive) {
File basedir = pomFile.getParentFile();
-
List<File> moduleFiles = new ArrayList<>();
-
for (String module : model.getModules()) {
if (StringUtils.isEmpty(module)) {
continue;
@@ -491,11 +492,13 @@ public class CachingProjectBuilder
interimResult.modules = new ArrayList<>();
if (!build(results, interimResult.modules, projectIndex, moduleFiles, aggregatorFiles, false,
- recursive, config)) {
+ recursive, config, poolBuilder)) {
noErrors = false;
}
}
+ projectIndex.put(pomFile, project);
+
return noErrors;
}
@@ -524,17 +527,8 @@ public class CachingProjectBuilder
}
- private void populateReactorModelPool(ReactorModelPool reactorModelPool, List<InterimResult> interimResults) {
- for (InterimResult interimResult : interimResults) {
- Model model = interimResult.result.getEffectiveModel();
- reactorModelPool.put(model.getGroupId(), model.getArtifactId(), model.getVersion(), model.getPomFile());
-
- populateReactorModelPool(reactorModelPool, interimResult.modules);
- }
- }
-
private boolean build(List<ProjectBuildingResult> results, List<MavenProject> projects,
- Map<String, MavenProject> projectIndex, List<InterimResult> interimResults,
+ Map<File, MavenProject> projectIndex, List<InterimResult> interimResults,
ProjectBuildingRequest request, Map<File, Boolean> profilesXmls,
RepositorySystemSession session) {
boolean noErrors = true;
@@ -569,9 +563,11 @@ public class CachingProjectBuilder
results.add(new DefaultProjectBuildingResult(project, result.getProblems(), resolutionResult));
} catch (ModelBuildingException e) {
DefaultProjectBuildingResult result = null;
- if (project == null) {
+ if (project == null || interimResult.result.getEffectiveModel() == null) {
result = new DefaultProjectBuildingResult(e.getModelId(), interimResult.pomFile, e.getProblems());
} else {
+ project.setModel(interimResult.result.getEffectiveModel());
+
result = new DefaultProjectBuildingResult(project, e.getProblems(), null);
}
results.add(result);
@@ -584,14 +580,13 @@ public class CachingProjectBuilder
}
@SuppressWarnings("checkstyle:methodlength")
- private void initProject(MavenProject project, Map<String, MavenProject> projects,
+ private void initProject(MavenProject project, Map<File, MavenProject> projects,
boolean buildParentIfNotExisting, ModelBuildingResult result,
Map<File, Boolean> profilesXmls, ProjectBuildingRequest projectBuildingRequest) {
Model model = result.getEffectiveModel();
project.setModel(model);
- project.setOriginalModel(result.getRawModel());
- project.setFile(model.getPomFile());
+ project.setOriginalModel(result.getFileModel());
initParent(project, projects, buildParentIfNotExisting, result, projectBuildingRequest);
@@ -618,14 +613,6 @@ public class CachingProjectBuilder
project.setInjectedProfileIds(modelId, getProfileIds(result.getActivePomProfiles(modelId)));
}
- String modelId = findProfilesXml(result, profilesXmls);
- if (modelId != null) {
- ModelProblem problem = new DefaultModelProblem("Detected profiles.xml alongside " + modelId
- + ", this file is no longer supported and was ignored" + ", please use the settings.xml instead",
- ModelProblem.Severity.WARNING, ModelProblem.Version.V30, model, -1, -1, null);
- result.getProblems().add(problem);
- }
-
//
// All the parts that were taken out of MavenProject for Maven 4.0.0
//
@@ -747,7 +734,7 @@ public class CachingProjectBuilder
try {
DeploymentRepository r = project.getDistributionManagement().getRepository();
if (!StringUtils.isEmpty(r.getId()) && !StringUtils.isEmpty(r.getUrl())) {
- ArtifactRepository repo = repositorySystem.buildArtifactRepository(r);
+ ArtifactRepository repo = MavenRepositorySystem.buildArtifactRepository(r);
repositorySystem.injectProxy(projectBuildingRequest.getRepositorySession(),
Arrays.asList(repo));
repositorySystem.injectAuthentication(projectBuildingRequest.getRepositorySession(),
@@ -766,7 +753,7 @@ public class CachingProjectBuilder
try {
DeploymentRepository r = project.getDistributionManagement().getSnapshotRepository();
if (!StringUtils.isEmpty(r.getId()) && !StringUtils.isEmpty(r.getUrl())) {
- ArtifactRepository repo = repositorySystem.buildArtifactRepository(r);
+ ArtifactRepository repo = MavenRepositorySystem.buildArtifactRepository(r);
repositorySystem.injectProxy(projectBuildingRequest.getRepositorySession(),
Arrays.asList(repo));
repositorySystem.injectAuthentication(projectBuildingRequest.getRepositorySession(),
@@ -780,7 +767,7 @@ public class CachingProjectBuilder
}
}
- private void initParent(MavenProject project, Map<String, MavenProject> projects, boolean buildParentIfNotExisting,
+ private void initParent(MavenProject project, Map<File, MavenProject> projects, boolean buildParentIfNotExisting,
ModelBuildingResult result, ProjectBuildingRequest projectBuildingRequest) {
Model parentModel = result.getModelIds().size() > 1 && !result.getModelIds().get(1).isEmpty()
? result.getRawModel(result.getModelIds().get(1))
@@ -797,7 +784,7 @@ public class CachingProjectBuilder
// org.apache.maven.its.mng4834:parent:0.1
String parentModelId = result.getModelIds().get(1);
File parentPomFile = result.getRawModel(parentModelId).getPomFile();
- MavenProject parent = projects.get(parentModelId);
+ MavenProject parent = projects.get(parentPomFile);
if (parent == null && buildParentIfNotExisting) {
//
// At this point the DefaultModelBuildingListener has fired and it populates the
@@ -872,28 +859,6 @@ public class CachingProjectBuilder
return version;
}
- private String findProfilesXml(ModelBuildingResult result, Map<File, Boolean> profilesXmls) {
- for (String modelId : result.getModelIds()) {
- Model model = result.getRawModel(modelId);
-
- File basedir = model.getProjectDirectory();
- if (basedir == null) {
- break;
- }
-
- Boolean profilesXml = profilesXmls.get(basedir);
- if (profilesXml == null) {
- profilesXml = new File(basedir, "profiles.xml").exists();
- profilesXmls.put(basedir, profilesXml);
- }
- if (profilesXml) {
- return modelId;
- }
- }
-
- return null;
- }
-
/**
* InternalConfig
*/
@@ -907,21 +872,20 @@ public class CachingProjectBuilder
private final ReactorModelPool modelPool;
- private final ModelCache modelCache;
+ private final TransformerContextBuilder transformerContextBuilder;
- InternalConfig(ProjectBuildingRequest request, ReactorModelPool modelPool, ModelCache modelCache) {
+ InternalConfig(ProjectBuildingRequest request, ReactorModelPool modelPool,
+ TransformerContextBuilder transformerContextBuilder) {
this.request = request;
this.modelPool = modelPool;
- this.modelCache = modelCache;
+ this.transformerContextBuilder = transformerContextBuilder;
+
session = LegacyLocalRepositoryManager.overlay(request.getLocalRepository(), request.getRepositorySession(),
repoSystem);
repositories = RepositoryUtils.toRepos(request.getRemoteRepositories());
- }
- }
+ }
- private ModelCache getModelCache() {
- return this.modelCache;
}
}
diff --git a/daemon/src/main/java/org/apache/maven/project/SnapshotModelCache.java b/daemon/src/main/java/org/apache/maven/project/SnapshotModelCache.java
index b4aee74..c80f69e 100644
--- a/daemon/src/main/java/org/apache/maven/project/SnapshotModelCache.java
+++ b/daemon/src/main/java/org/apache/maven/project/SnapshotModelCache.java
@@ -22,9 +22,9 @@ public class SnapshotModelCache implements ModelCache {
private final ModelCache globalCache;
private final ModelCache reactorCache;
- public SnapshotModelCache(ModelCache globalCache) {
+ public SnapshotModelCache(ModelCache globalCache, ModelCache reactorCache) {
this.globalCache = globalCache;
- this.reactorCache = new ReactorModelCache();
+ this.reactorCache = reactorCache;
}
@Override
diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/execution/BuildResumptionAnalyzer.java b/daemon/src/main/java/org/mvndaemon/mvnd/execution/BuildResumptionAnalyzer.java
deleted file mode 100644
index 07d0fc7..0000000
--- a/daemon/src/main/java/org/mvndaemon/mvnd/execution/BuildResumptionAnalyzer.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2019 the original author or authors.
- *
- * Licensed 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.
- */
-package org.mvndaemon.mvnd.execution;
-
-/*
- * 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.
- */
-import java.util.Optional;
-import org.apache.maven.execution.MavenExecutionResult;
-
-/**
- * Instances of this class are responsible for determining whether it makes sense to "resume" a build (i.e., using
- * the {@code --resume} flag.
- */
-public interface BuildResumptionAnalyzer {
- /**
- * Construct an instance of {@link BuildResumptionData} based on the outcome of the current Maven build.
- *
- * @param result Outcome of the current Maven build.
- * @return A {@link BuildResumptionData} instance or {@link Optional#empty()} if resuming the build is not
- * possible.
- */
- Optional<BuildResumptionData> determineBuildResumptionData(final MavenExecutionResult result);
-}
diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/execution/BuildResumptionData.java b/daemon/src/main/java/org/mvndaemon/mvnd/execution/BuildResumptionData.java
deleted file mode 100644
index cbe3eb4..0000000
--- a/daemon/src/main/java/org/mvndaemon/mvnd/execution/BuildResumptionData.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2019 the original author or authors.
- *
- * Licensed 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.
- */
-package org.mvndaemon.mvnd.execution;
-
-/*
- * 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.
- */
-import java.util.List;
-
-/**
- * This class holds the information required to enable resuming a Maven build with {@code --resume}.
- */
-public class BuildResumptionData {
- /**
- * The list of projects that remain to be built.
- */
- private final List<String> remainingProjects;
-
- public BuildResumptionData(final List<String> remainingProjects) {
- this.remainingProjects = remainingProjects;
- }
-
- /**
- * Returns the projects that still need to be built when resuming.
- *
- * @return A list containing the group and artifact id of the projects.
- */
- public List<String> getRemainingProjects() {
- return this.remainingProjects;
- }
-
-}
diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/execution/BuildResumptionDataRepository.java b/daemon/src/main/java/org/mvndaemon/mvnd/execution/BuildResumptionDataRepository.java
deleted file mode 100644
index 52b998e..0000000
--- a/daemon/src/main/java/org/mvndaemon/mvnd/execution/BuildResumptionDataRepository.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2019 the original author or authors.
- *
- * Licensed 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.
- */
-package org.mvndaemon.mvnd.execution;
-
-/*
- * 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.
- */
-import org.apache.maven.execution.MavenExecutionRequest;
-import org.apache.maven.project.MavenProject;
-
-/**
- * Instances of this interface retrieve and store data for the --resume / -r feature. This data is used to ensure newer
- * builds of the same project, that have the -r command-line flag, skip successfully built projects during earlier
- * invocations of Maven.
- */
-public interface BuildResumptionDataRepository {
- /**
- * Persists any data needed to resume the build at a later point in time, using a new Maven invocation. This method
- * may also decide it is not needed or meaningful to persist such data, and return <code>false</code> to indicate
- * so.
- *
- * @param rootProject The root project that is being built.
- * @param buildResumptionData Information needed to resume the build.
- * @throws BuildResumptionPersistenceException When an error occurs while persisting data.
- */
- void persistResumptionData(final MavenProject rootProject, final BuildResumptionData buildResumptionData)
- throws BuildResumptionPersistenceException;
-
- /**
- * Uses previously stored resumption data to enrich an existing execution request.
- *
- * @param request The execution request that will be enriched.
- * @param rootProject The root project that is being built.
- */
- void applyResumptionData(final MavenExecutionRequest request, final MavenProject rootProject);
-
- /**
- * Removes previously stored resumption data.
- *
- * @param rootProject The root project that is being built.
- */
- void removeResumptionData(final MavenProject rootProject);
-
-}
diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/execution/BuildResumptionPersistenceException.java b/daemon/src/main/java/org/mvndaemon/mvnd/execution/BuildResumptionPersistenceException.java
deleted file mode 100644
index c80bede..0000000
--- a/daemon/src/main/java/org/mvndaemon/mvnd/execution/BuildResumptionPersistenceException.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2019 the original author or authors.
- *
- * Licensed 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.
- */
-package org.mvndaemon.mvnd.execution;
-
-/*
- * 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.
- */
-
-/**
- * This exception will be thrown when something fails while persisting build resumption data.
- *
- * @see BuildResumptionDataRepository#persistResumptionData
- */
-public class BuildResumptionPersistenceException extends Exception {
- public BuildResumptionPersistenceException(String message, Throwable cause) {
- super(message, cause);
- }
-}
diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/execution/DefaultBuildResumptionAnalyzer.java b/daemon/src/main/java/org/mvndaemon/mvnd/execution/DefaultBuildResumptionAnalyzer.java
deleted file mode 100644
index 844169f..0000000
--- a/daemon/src/main/java/org/mvndaemon/mvnd/execution/DefaultBuildResumptionAnalyzer.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2019 the original author or authors.
- *
- * Licensed 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.
- */
-package org.mvndaemon.mvnd.execution;
-
-/*
- * 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.
- */
-import java.util.List;
-import java.util.Optional;
-import java.util.stream.Collectors;
-import javax.inject.Named;
-import javax.inject.Singleton;
-import org.apache.maven.execution.BuildFailure;
-import org.apache.maven.execution.BuildSuccess;
-import org.apache.maven.execution.MavenExecutionResult;
-import org.apache.maven.project.MavenProject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Default implementation of {@link BuildResumptionAnalyzer}.
- */
-@Named
-@Singleton
-public class DefaultBuildResumptionAnalyzer implements BuildResumptionAnalyzer {
- private static final Logger LOGGER = LoggerFactory.getLogger(DefaultBuildResumptionAnalyzer.class);
-
- @Override
- public Optional<BuildResumptionData> determineBuildResumptionData(final MavenExecutionResult result) {
- if (!result.hasExceptions()) {
- return Optional.empty();
- }
-
- List<MavenProject> sortedProjects = result.getTopologicallySortedProjects();
-
- boolean hasNoSuccess = sortedProjects.stream()
- .noneMatch(project -> result.getBuildSummary(project) instanceof BuildSuccess);
-
- if (hasNoSuccess) {
- return Optional.empty();
- }
-
- List<String> remainingProjects = sortedProjects.stream()
- .filter(project -> result.getBuildSummary(project) == null
- || result.getBuildSummary(project) instanceof BuildFailure)
- .map(project -> project.getGroupId() + ":" + project.getArtifactId())
- .collect(Collectors.toList());
-
- if (remainingProjects.isEmpty()) {
- LOGGER.info("No remaining projects found, resuming the build would not make sense.");
- return Optional.empty();
- }
-
- return Optional.of(new BuildResumptionData(remainingProjects));
- }
-
-}
diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/execution/DefaultBuildResumptionDataRepository.java b/daemon/src/main/java/org/mvndaemon/mvnd/execution/DefaultBuildResumptionDataRepository.java
deleted file mode 100644
index 8bc3817..0000000
--- a/daemon/src/main/java/org/mvndaemon/mvnd/execution/DefaultBuildResumptionDataRepository.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright 2019 the original author or authors.
- *
- * Licensed 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.
- */
-package org.mvndaemon.mvnd.execution;
-
-/*
- * 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.
- */
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Properties;
-import java.util.stream.Stream;
-import javax.inject.Named;
-import javax.inject.Singleton;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.maven.execution.MavenExecutionRequest;
-import org.apache.maven.project.MavenProject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This implementation of {@link BuildResumptionDataRepository} persists information in a properties file. The file is
- * stored in the build output directory under the Maven execution root.
- */
-@Named
-@Singleton
-public class DefaultBuildResumptionDataRepository implements BuildResumptionDataRepository {
- private static final String RESUME_PROPERTIES_FILENAME = "resume.properties";
- private static final String REMAINING_PROJECTS = "remainingProjects";
- private static final String PROPERTY_DELIMITER = ", ";
- private static final Logger LOGGER = LoggerFactory.getLogger(DefaultBuildResumptionDataRepository.class);
-
- @Override
- public void persistResumptionData(MavenProject rootProject, BuildResumptionData buildResumptionData)
- throws BuildResumptionPersistenceException {
- Path directory = Paths.get(rootProject.getBuild().getDirectory());
- persistResumptionData(directory, buildResumptionData);
- }
-
- public void persistResumptionData(Path directory, BuildResumptionData buildResumptionData)
- throws BuildResumptionPersistenceException {
- Properties properties = convertToProperties(buildResumptionData);
-
- Path resumeProperties = directory.resolve(RESUME_PROPERTIES_FILENAME);
- try {
- Files.createDirectories(resumeProperties.getParent());
- try (Writer writer = Files.newBufferedWriter(resumeProperties)) {
- properties.store(writer, null);
- }
- } catch (IOException e) {
- String message = "Could not create " + RESUME_PROPERTIES_FILENAME + " file.";
- throw new BuildResumptionPersistenceException(message, e);
- }
- }
-
- private Properties convertToProperties(final BuildResumptionData buildResumptionData) {
- Properties properties = new Properties();
-
- String value = String.join(PROPERTY_DELIMITER, buildResumptionData.getRemainingProjects());
- properties.setProperty(REMAINING_PROJECTS, value);
-
- return properties;
- }
-
- @Override
- public void applyResumptionData(MavenExecutionRequest request, MavenProject rootProject) {
- Path directory = Paths.get(rootProject.getBuild().getDirectory());
- applyResumptionData(request, directory);
- }
-
- public void applyResumptionData(MavenExecutionRequest request, Path directory) {
- Properties properties = loadResumptionFile(directory);
- applyResumptionProperties(request, properties);
- }
-
- @Override
- public void removeResumptionData(MavenProject rootProject) {
- Path directory = Paths.get(rootProject.getBuild().getDirectory());
- removeResumptionData(directory);
- }
-
- public void removeResumptionData(Path directory) {
- Path resumeProperties = directory.resolve(RESUME_PROPERTIES_FILENAME);
- try {
- Files.deleteIfExists(resumeProperties);
- } catch (IOException e) {
- LOGGER.warn("Could not delete {} file. ", RESUME_PROPERTIES_FILENAME, e);
- }
- }
-
- private Properties loadResumptionFile(Path rootBuildDirectory) {
- Properties properties = new Properties();
- Path path = rootBuildDirectory.resolve(RESUME_PROPERTIES_FILENAME);
- if (!Files.exists(path)) {
- LOGGER.warn("The {} file does not exist. The --resume / -r feature will not work.", path);
- return properties;
- }
-
- try (Reader reader = Files.newBufferedReader(path)) {
- properties.load(reader);
- } catch (IOException e) {
- LOGGER.warn("Unable to read {}. The --resume / -r feature will not work.", path);
- }
-
- return properties;
- }
-
- // This method is made package-private for testing purposes
- void applyResumptionProperties(MavenExecutionRequest request, Properties properties) {
- if (properties.containsKey(REMAINING_PROJECTS)
- && StringUtils.isEmpty(request.getResumeFrom())) {
- String propertyValue = properties.getProperty(REMAINING_PROJECTS);
- Stream.of(propertyValue.split(PROPERTY_DELIMITER))
- .filter(StringUtils::isNotEmpty)
- .forEach(request.getSelectedProjects()::add);
- LOGGER.info("Resuming from {} due to the --resume / -r feature.", propertyValue);
- }
- }
-}
diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/plugin/CachingPluginVersionResolver.java b/daemon/src/main/java/org/mvndaemon/mvnd/plugin/CachingPluginVersionResolver.java
index 56d6398..4ecb450 100644
--- a/daemon/src/main/java/org/mvndaemon/mvnd/plugin/CachingPluginVersionResolver.java
+++ b/daemon/src/main/java/org/mvndaemon/mvnd/plugin/CachingPluginVersionResolver.java
@@ -19,15 +19,20 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
+import org.apache.maven.artifact.repository.metadata.io.MetadataReader;
+import org.apache.maven.plugin.MavenPluginManager;
import org.apache.maven.plugin.version.PluginVersionRequest;
import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.plugin.version.PluginVersionResolver;
import org.apache.maven.plugin.version.PluginVersionResult;
import org.apache.maven.plugin.version.internal.DefaultPluginVersionResolver;
+import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.SessionData;
import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.version.VersionScheme;
import org.eclipse.sisu.Priority;
import org.eclipse.sisu.Typed;
@@ -39,6 +44,12 @@ public class CachingPluginVersionResolver extends DefaultPluginVersionResolver {
private static final Object CACHE_KEY = new Object();
+ @Inject
+ public CachingPluginVersionResolver(RepositorySystem repositorySystem, MetadataReader metadataReader,
+ MavenPluginManager pluginManager, VersionScheme versionScheme) {
+ super(repositorySystem, metadataReader, pluginManager, versionScheme);
+ }
+
@Override
public PluginVersionResult resolve(PluginVersionRequest request) throws PluginVersionResolutionException {
Map<String, PluginVersionResult> cache = getCache(request.getRepositorySession().getData());
diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/plugin/CliMavenPluginManager.java b/daemon/src/main/java/org/mvndaemon/mvnd/plugin/CliMavenPluginManager.java
index 9edb2b8..78ac8c8 100644
--- a/daemon/src/main/java/org/mvndaemon/mvnd/plugin/CliMavenPluginManager.java
+++ b/daemon/src/main/java/org/mvndaemon/mvnd/plugin/CliMavenPluginManager.java
@@ -47,13 +47,11 @@ import org.apache.maven.classrealm.ClassRealmManager;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule;
import org.apache.maven.model.Plugin;
-import org.apache.maven.monitor.logging.DefaultLog;
import org.apache.maven.plugin.ContextEnabled;
import org.apache.maven.plugin.DebugConfigurationListener;
import org.apache.maven.plugin.ExtensionRealmCache;
import org.apache.maven.plugin.InvalidPluginDescriptorException;
import org.apache.maven.plugin.MavenPluginManager;
-import org.apache.maven.plugin.MavenPluginValidator;
import org.apache.maven.plugin.Mojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoNotFoundException;
@@ -72,6 +70,7 @@ import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder;
+import org.apache.maven.plugin.internal.MojoLogWrapper;
import org.apache.maven.plugin.internal.PluginDependenciesResolver;
import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
import org.apache.maven.plugin.version.PluginVersionRequest;
@@ -97,7 +96,6 @@ import org.codehaus.plexus.component.repository.exception.ComponentLookupExcepti
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.configuration.PlexusConfigurationException;
import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
-import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.LoggerManager;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils;
@@ -112,6 +110,8 @@ import org.eclipse.sisu.Priority;
import org.eclipse.sisu.Typed;
import org.mvndaemon.mvnd.cache.invalidating.InvalidatingPluginDescriptorCache;
import org.mvndaemon.mvnd.cache.invalidating.InvalidatingPluginRealmCache;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/*
* gnodet: This file is based on maven DefaultMavenPluginManager and changed in order
@@ -143,8 +143,7 @@ public class CliMavenPluginManager
*/
public static final String KEY_EXTENSIONS_REALMS = CliMavenPluginManager.class.getName() + "/extensionsRealms";
- @Inject
- private Logger logger;
+ private final Logger logger = LoggerFactory.getLogger(getClass());
@Inject
private LoggerManager loggerManager;
@@ -236,13 +235,12 @@ public class CliMavenPluginManager
throw new PluginDescriptorParsingException(plugin, pluginFile.getAbsolutePath(), e);
}
- MavenPluginValidator validator = new MavenPluginValidator(pluginArtifact);
-
- validator.validate(pluginDescriptor);
+ List<String> errors = new ArrayList<>();
+ validate(pluginArtifact, pluginDescriptor, errors);
- if (validator.hasErrors()) {
+ if (!errors.isEmpty()) {
throw new InvalidPluginDescriptorException(
- "Invalid plugin descriptor for " + plugin.getId() + " (" + pluginFile + ")", validator.getErrors());
+ "Invalid plugin descriptor for " + plugin.getId() + " (" + pluginFile + ")", errors);
}
pluginDescriptor.setPluginArtifact(pluginArtifact);
@@ -250,6 +248,20 @@ public class CliMavenPluginManager
return pluginDescriptor;
}
+ private void validate(Artifact pluginArtifact, PluginDescriptor pluginDescriptor, List<String> errors) {
+ if (!pluginArtifact.getGroupId().equals(pluginDescriptor.getGroupId())) {
+ errors.add("Plugin's descriptor contains the wrong group ID: " + pluginDescriptor.getGroupId());
+ }
+
+ if (!pluginArtifact.getArtifactId().equals(pluginDescriptor.getArtifactId())) {
+ errors.add("Plugin's descriptor contains the wrong artifact ID: " + pluginDescriptor.getArtifactId());
+ }
+
+ if (!pluginArtifact.getBaseVersion().equals(pluginDescriptor.getVersion())) {
+ errors.add("Plugin's descriptor contains the wrong version: " + pluginDescriptor.getVersion());
+ }
+ }
+
private String getPluginDescriptorLocation() {
return "META-INF/maven/plugin.xml";
}
@@ -516,8 +528,8 @@ public class CliMavenPluginManager
}
if (mojo instanceof Mojo) {
- Logger mojoLogger = loggerManager.getLoggerForComponent(mojoDescriptor.getImplementation());
- ((Mojo) mojo).setLog(new DefaultLog(mojoLogger));
+ org.slf4j.Logger mojoLogger = LoggerFactory.getLogger(mojoDescriptor.getImplementation());
+ ((Mojo) mojo).setLog(new MojoLogWrapper(mojoLogger));
}
Xpp3Dom dom = mojoExecution.getConfiguration();
diff --git a/daemon/src/main/resources/META-INF/maven/extension.xml b/daemon/src/main/resources/META-INF/maven/extension.xml
index 71cacc7..bf06d2f 100644
--- a/daemon/src/main/resources/META-INF/maven/extension.xml
+++ b/daemon/src/main/resources/META-INF/maven/extension.xml
@@ -21,5 +21,10 @@ under the License.
<extension>
<exportedPackages>
<exportedPackage>org.apache.commons.logging.*</exportedPackage>
+ <exportedPackage>org.codehaus.plexus.components.interactivity.*</exportedPackage>
</exportedPackages>
+
+ <exportedArtifacts>
+ <exportedArtifact>org.codehaus.plexus:plexus-interactivity-api</exportedArtifact>
+ </exportedArtifacts>
</extension>
diff --git a/dist/src/main/provisio/maven-distro.xml b/dist/src/main/provisio/maven-distro.xml
index 06b4281..145e2f8 100644
--- a/dist/src/main/provisio/maven-distro.xml
+++ b/dist/src/main/provisio/maven-distro.xml
@@ -20,12 +20,13 @@
<artifactSet to="/mvn">
<artifact id="org.apache.maven:apache-maven:tar.gz:bin">
<unpack useRoot="false"
- excludes="lib/*slf4j*,conf/logging/*,lib/maven-slf4j-provider*,bin/mvn*,lib/jansi-*.jar,lib/jansi-native/*,lib/maven-resolver-api-*,lib/maven-resolver-impl-*,lib/maven-resolver-spi-*,lib/maven-resolver-util-*,lib/maven-resolver-connector-*,lib/maven-resolver-transport-*"/>
+ excludes="conf/logging/*,lib/maven-slf4j-provider*,bin/mvn*,lib/jansi-*.jar,lib/jansi-native/*,lib/plexus-utils-3.*"/>
</artifact>
</artifactSet>
<artifactSet to="/mvn/lib">
<exclusion id="javax.annotation:javax.annotation-api"/>
+ <exclusion id="org.codehaus.plexus:plexus-utils"/>
<artifact id="org.apache.maven.resolver:maven-resolver-api"/>
<artifact id="org.apache.maven.resolver:maven-resolver-impl"/>
<artifact id="org.apache.maven.resolver:maven-resolver-spi"/>
@@ -38,6 +39,7 @@
<exclusion id="org.slf4j:slf4j-api"/>
<artifact id="org.apache.maven.daemon:mvnd-daemon:${project.version}">
<exclusion id="org.codehaus.plexus:plexus-classworlds"/>
+ <exclusion id="org.codehaus.plexus:plexus-utils"/>
<exclusion id="*:cdi-api"/>
<exclusion id="*:commons-cli"/>
<exclusion id="*:commons-io"/>
@@ -45,7 +47,10 @@
<exclusion id="*:guava"/>
<exclusion id="*:guice"/>
<exclusion id="*:javax.inject"/>
+ <exclusion id="*:jcl-over-slf4j"/>
+ <exclusion id="*:jul-to-slf4j"/>
<exclusion id="*:jsr250-api"/>
+ <exclusion id="*:log4j-over-slf4j"/>
<exclusion id="*:maven-artifact"/>
<exclusion id="*:maven-builder-support"/>
<exclusion id="*:maven-core"/>
@@ -70,6 +75,7 @@
<exclusion id="*:plexus-sec-dispatcher"/>
<exclusion id="*:plexus-utils"/>
<exclusion id="*:plexus-container-default"/>
+ <exclusion id="*:slf4j-api"/>
</artifact>
<artifact id="org.apache.maven.daemon:mvnd-client:${project.version}">
<exclusion id="*:*"/>
diff --git a/integration-tests/src/test/java/org/mvndaemon/mvnd/it/InteractiveTest.java b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/InteractiveTest.java
index a6d6e2e..5cf28af 100644
--- a/integration-tests/src/test/java/org/mvndaemon/mvnd/it/InteractiveTest.java
+++ b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/InteractiveTest.java
@@ -19,6 +19,7 @@ import java.io.IOException;
import javax.inject.Inject;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
import org.mvndaemon.mvnd.assertj.TestClientOutput;
import org.mvndaemon.mvnd.client.Client;
import org.mvndaemon.mvnd.client.DaemonParameters;
@@ -27,6 +28,7 @@ import org.mvndaemon.mvnd.common.Message.Prompt;
import org.mvndaemon.mvnd.junit.MvndTest;
@MvndTest(projectDir = "src/test/projects/single-module")
+@Timeout(300)
public class InteractiveTest {
@Inject
diff --git a/integration-tests/src/test/java/org/mvndaemon/mvnd/it/NewManagedModuleNativeIT.java b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/NewManagedModuleNativeIT.java
index 21e6897..e809bc4 100644
--- a/integration-tests/src/test/java/org/mvndaemon/mvnd/it/NewManagedModuleNativeIT.java
+++ b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/NewManagedModuleNativeIT.java
@@ -61,6 +61,10 @@ public class NewManagedModuleNativeIT {
registry.awaitIdle(d.getId());
/* Do the changes */
+ System.gc();
+ Thread.sleep(100);
+ System.gc();
+
final Path srcDir = parentDir.resolve("../changes").normalize();
try (Stream<Path> files = Files.walk(srcDir)) {
files.forEach(source -> {
diff --git a/pom.xml b/pom.xml
index 4c4b5ad..667a66e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,8 +64,8 @@
<jline.version>3.21.0</jline.version>
<junit.jupiter.version>5.7.2</junit.jupiter.version>
<logback.version>1.2.10</logback.version>
- <maven.version>3.8.6</maven.version>
- <maven.resolver.version>1.7.3</maven.resolver.version>
+ <maven.version>4.0.0-alpha-2</maven.version>
+ <maven.resolver.version>1.8.2</maven.resolver.version>
<slf4j.version>1.7.35</slf4j.version>
<sisu.version>0.3.5</sisu.version>
@@ -412,6 +412,13 @@ limitations under the License.</inlineHeader>
<skip>${format.skip}</skip>
<cachedir>${project.build.directory}/cache</cachedir>
</configuration>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>${maven.version}</version>
+ </dependency>
+ </dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>