From 895381b43fbfa11d753af99c2b07f7d525083a2d Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Sat, 19 Nov 2022 16:56:26 +0100 Subject: [PATCH] Switch to maven 4.0.0-alpha-2 (#718) --- .../org/apache/maven/cli/DaemonMavenCli.java | 529 +++++++++--------- .../maven/project/CachingProjectBuilder.java | 192 +++---- .../maven/project/SnapshotModelCache.java | 4 +- .../execution/BuildResumptionAnalyzer.java | 52 -- .../mvnd/execution/BuildResumptionData.java | 60 -- .../BuildResumptionDataRepository.java | 72 --- .../BuildResumptionPersistenceException.java | 46 -- .../DefaultBuildResumptionAnalyzer.java | 85 --- .../DefaultBuildResumptionDataRepository.java | 150 ----- .../plugin/CachingPluginVersionResolver.java | 11 + .../mvnd/plugin/CliMavenPluginManager.java | 36 +- .../resources/META-INF/maven/extension.xml | 5 + dist/src/main/provisio/maven-distro.xml | 8 +- .../mvndaemon/mvnd/it/InteractiveTest.java | 2 + .../mvnd/it/NewManagedModuleNativeIT.java | 4 + pom.xml | 11 +- 16 files changed, 407 insertions(+), 860 deletions(-) delete mode 100644 daemon/src/main/java/org/mvndaemon/mvnd/execution/BuildResumptionAnalyzer.java delete mode 100644 daemon/src/main/java/org/mvndaemon/mvnd/execution/BuildResumptionData.java delete mode 100644 daemon/src/main/java/org/mvndaemon/mvnd/execution/BuildResumptionDataRepository.java delete mode 100644 daemon/src/main/java/org/mvndaemon/mvnd/execution/BuildResumptionPersistenceException.java delete mode 100644 daemon/src/main/java/org/mvndaemon/mvnd/execution/DefaultBuildResumptionAnalyzer.java delete mode 100644 daemon/src/main/java/org/mvndaemon/mvnd/execution/DefaultBuildResumptionDataRepository.java 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 5d23c9a4..e0883164 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 -r"); } else if (!failedProjects.isEmpty()) { List 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,208 +995,50 @@ 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 goals = commandLine.getArgList(); - - boolean recursive = true; - - // this is the default behavior. - String reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST; - - if (commandLine.hasOption(CLIManager.NON_RECURSIVE)) { - recursive = false; - } - - 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 (commandLine.hasOption(CLIManager.OFFLINE)) { - request.setOffline(true); - } - - boolean updateSnapshots = false; - - if (commandLine.hasOption(CLIManager.UPDATE_SNAPSHOTS)) { - updateSnapshots = true; - } - - String globalChecksumPolicy = null; - - 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; - } - + boolean quiet = cliRequest.quiet; + boolean verbose = cliRequest.verbose; + request.setShowErrors(cliRequest.showErrors); // default: false File baseDirectory = new File(workingDirectory, "").getAbsoluteFile(); - // ---------------------------------------------------------------------- - // Profile Activation - // ---------------------------------------------------------------------- - - List activeProfiles = new ArrayList<>(); - - List inactiveProfiles = new ArrayList<>(); - - 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); - } - } - } - } - } + 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); ExecutionEventLogger executionEventLogger = new ExecutionEventLogger(); executionListener.init( eventSpyDispatcher.chainListener(executionEventLogger), buildEventListener); - 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); - } else if (modelProcessor != null) { - File pom = modelProcessor.locatePom(baseDirectory); - - if (pom.isFile()) { - request.setPom(pom); - } - } - if ((request.getPom() != null) && (request.getPom().getParentFile() != null)) { request.setBaseDirectory(request.getPom().getParentFile()); } - if (commandLine.hasOption(RESUME)) { - new DefaultBuildResumptionDataRepository() - .applyResumptionData(request, Paths.get(request.getBaseDirectory()).resolve("target")); - } - - if (commandLine.hasOption(CLIManager.RESUME_FROM)) { - request.setResumeFrom(commandLine.getOptionValue(CLIManager.RESUME_FROM)); - } - - if (commandLine.hasOption(CLIManager.PROJECT_LIST)) { - String[] projectOptionValues = commandLine.getOptionValues(CLIManager.PROJECT_LIST); - - List inclProjects = new ArrayList<>(); - List exclProjects = new ArrayList<>(); - - if (projectOptionValues != null) { - for (String projectOptionValue : projectOptionValues) { - StringTokenizer projectTokens = new StringTokenizer(projectOptionValue, ","); - - while (projectTokens.hasMoreTokens()) { - String projectAction = projectTokens.nextToken().trim(); - - if (projectAction.startsWith("-") || projectAction.startsWith("!")) { - exclProjects.add(projectAction.substring(1)); - } else if (projectAction.startsWith("+")) { - inclProjects.add(projectAction.substring(1)); - } else { - inclProjects.add(projectAction); - } - } - } - } - - 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); - } - - String localRepoProperty = request.getUserProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY); - - if (localRepoProperty == null) { - localRepoProperty = request.getSystemProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY); - } - - if (localRepoProperty != null) { - request.setLocalRepositoryPath(localRepoProperty); - } - + request.setResumeFrom(commandLine.getOptionValue(CLIManager.RESUME_FROM)); + enableOnPresentOption(commandLine, CLIManager.RESUME, request::setResume); + request.setMakeBehavior(determineMakeBehavior(commandLine)); request.setCacheNotFound(true); request.setCacheTransferError(false); + performProjectActivation(commandLine, request.getProjectActivation()); + performProfileActivation(commandLine, request.getProfileActivation()); + + final String localRepositoryPath = determineLocalRepositoryPath(request); + if (localRepositoryPath != null) { + request.setLocalRepositoryPath(localRepositoryPath); + } + // // Builder, concurrency and parallelism // @@ -1224,34 +1047,233 @@ public class DaemonMavenCli { // 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; + final String threadConfiguration = commandLine.getOptionValue(CLIManager.THREADS); if (threadConfiguration != null) { - // - // Default to the standard multithreaded builder - // - request.setBuilderId("multithreaded"); - - if (threadConfiguration.contains("C")) { - request.setDegreeOfConcurrency(calculateDegreeOfConcurrencyWithCoreMultiplier(threadConfiguration)); - } else { - request.setDegreeOfConcurrency(Integer.parseInt(threadConfiguration)); + int degreeOfConcurrency = calculateDegreeOfConcurrency(threadConfiguration); + if (degreeOfConcurrency > 1) { + request.setBuilderId("multithreaded"); + request.setDegreeOfConcurrency(degreeOfConcurrency); } } // // 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)); + request.setBuilderId(commandLine.getOptionValue(CLIManager.BUILDER, request.getBuilderId())); + } + + private String determineLocalRepositoryPath(final MavenExecutionRequest request) { + String userDefinedLocalRepo = request.getUserProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY); + if (userDefinedLocalRepo != null) { + return userDefinedLocalRepo; + } + + 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); + } + + if (alternatePomFile != null) { + File pom = resolveFile(new File(alternatePomFile), workingDirectory); + if (pom.isDirectory()) { + pom = new File(pom, "pom.xml"); + } + + return pom; + } else if (modelProcessor != null) { + File pom = modelProcessor.locatePom(baseDirectory); + + if (pom.isFile()) { + return pom; + } + } + + return null; + } + + // 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 (optionValues == null || optionValues.length == 0) { + return; + } + + 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); + } + + boolean optional = selector.charAt(0) == '?'; + selector = selector.substring(optional ? 1 : 0); + + projectActivation.addProjectActivation(selector, active, optional); + } + } } } - static int calculateDegreeOfConcurrencyWithCoreMultiplier(String threadConfiguration) { - int procs = Runtime.getRuntime().availableProcessors(); - return (int) (Float.parseFloat(threadConfiguration.replace("C", "")) * procs); + // 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; + } + + 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); + } + } + } + } + + private ExecutionListener determineExecutionListener(EventSpyDispatcher eventSpyDispatcher) { + ExecutionListener executionListener = new ExecutionEventLogger(); + if (eventSpyDispatcher != null) { + return eventSpyDispatcher.chainListener(executionListener); + } else { + return executionListener; + } + } + + 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; + } + } + + 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; + } + } + + 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; + } + } + + private void disableOnPresentOption(final CommandLine commandLine, + final String option, + final Consumer setting) { + if (commandLine.hasOption(option)) { + setting.accept(false); + } + } + + private void disableOnPresentOption(final CommandLine commandLine, + final char option, + final Consumer setting) { + disableOnPresentOption(commandLine, String.valueOf(option), setting); + } + + private void enableOnPresentOption(final CommandLine commandLine, + final String option, + final Consumer setting) { + if (commandLine.hasOption(option)) { + setting.accept(true); + } + } + + private void enableOnPresentOption(final CommandLine commandLine, + final char option, + final Consumer setting) { + enableOnPresentOption(commandLine, String.valueOf(option), setting); + } + + private void enableOnAbsentOption(final CommandLine commandLine, + final char option, + final Consumer setting) { + if (!commandLine.hasOption(option)) { + setting.accept(true); + } + } + + 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 9a919db4..0dfe7554 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. emptyMap(), true, - result, new HashMap(), 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 getProfileIds(List profiles) { - List 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 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 projectIndex = new HashMap<>(256); + Map projectIndex = new HashMap<>(256); - boolean noErrors = build(results, interimResults, projectIndex, pomFiles, new LinkedHashSet(), 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(), projectIndex, interimResults, request, - new HashMap(), 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 results, List interimResults, - Map projectIndex, List pomFiles, Set aggregatorFiles, - boolean isRoot, boolean recursive, InternalConfig config) { + Map projectIndex, List pomFiles, Set 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 results, List interimResults, - Map projectIndex, File pomFile, Set aggregatorFiles, - boolean isRoot, boolean recursive, InternalConfig config) { + Map projectIndex, File pomFile, Set 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(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 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 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 results, List projects, - Map projectIndex, List interimResults, + Map projectIndex, List interimResults, ProjectBuildingRequest request, Map 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 projects, + private void initProject(MavenProject project, Map projects, boolean buildParentIfNotExisting, ModelBuildingResult result, Map 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 projects, boolean buildParentIfNotExisting, + private void initParent(MavenProject project, Map 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 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 b4aee747..c80f69ef 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 07d0fc73..00000000 --- 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 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 cbe3eb4d..00000000 --- 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 remainingProjects; - - public BuildResumptionData(final List 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 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 52b998e9..00000000 --- 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 false 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 c80bede2..00000000 --- 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 844169f4..00000000 --- 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 determineBuildResumptionData(final MavenExecutionResult result) { - if (!result.hasExceptions()) { - return Optional.empty(); - } - - List sortedProjects = result.getTopologicallySortedProjects(); - - boolean hasNoSuccess = sortedProjects.stream() - .noneMatch(project -> result.getBuildSummary(project) instanceof BuildSuccess); - - if (hasNoSuccess) { - return Optional.empty(); - } - - List 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 8bc38176..00000000 --- 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 56d63982..4ecb4502 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 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 9edb2b86..78ac8c8d 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); + List errors = new ArrayList<>(); + validate(pluginArtifact, pluginDescriptor, errors); - validator.validate(pluginDescriptor); - - 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 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 71cacc72..bf06d2fb 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. org.apache.commons.logging.* + org.codehaus.plexus.components.interactivity.* + + + org.codehaus.plexus:plexus-interactivity-api + diff --git a/dist/src/main/provisio/maven-distro.xml b/dist/src/main/provisio/maven-distro.xml index 06b42810..145e2f88 100644 --- a/dist/src/main/provisio/maven-distro.xml +++ b/dist/src/main/provisio/maven-distro.xml @@ -20,12 +20,13 @@ + excludes="conf/logging/*,lib/maven-slf4j-provider*,bin/mvn*,lib/jansi-*.jar,lib/jansi-native/*,lib/plexus-utils-3.*"/> + @@ -38,6 +39,7 @@ + @@ -45,7 +47,10 @@ + + + @@ -70,6 +75,7 @@ + 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 a6d6e2ef..5cf28afc 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 21e6897f..e809bc46 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 files = Files.walk(srcDir)) { files.forEach(source -> { diff --git a/pom.xml b/pom.xml index 4c4b5adb..667a66e7 100644 --- a/pom.xml +++ b/pom.xml @@ -64,8 +64,8 @@ 3.21.0 5.7.2 1.2.10 - 3.8.6 - 1.7.3 + 4.0.0-alpha-2 + 1.8.2 1.7.35 0.3.5 @@ -412,6 +412,13 @@ limitations under the License. ${format.skip} ${project.build.directory}/cache + + + org.apache.maven + plexus-utils + ${maven.version} + + org.apache.maven.plugins