This is an automated email from the ASF dual-hosted git repository. cstamas 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 c4b5656d Bug: extension handling (#1282) c4b5656d is described below commit c4b5656d19ee7e5736155fe3a61a2d7588993032 Author: Tamas Cservenak <ta...@cservenak.net> AuthorDate: Fri Mar 7 19:02:57 2025 +0100 Bug: extension handling (#1282) mvnd still had mvn3 like code, just drop it and let base parser do the work. All the mvnd needs is filtering. Discriminating based on XML file hashes. Fixes #1280 --- .../mvndaemon/mvnd/client/DaemonParameters.java | 62 +++++++++++++++------- .../org/mvndaemon/mvnd/common/Environment.java | 9 ++-- .../org/apache/maven/cli/DaemonMavenParser.java | 35 ++---------- 3 files changed, 53 insertions(+), 53 deletions(-) diff --git a/client/src/main/java/org/mvndaemon/mvnd/client/DaemonParameters.java b/client/src/main/java/org/mvndaemon/mvnd/client/DaemonParameters.java index f63fb241..9f7b8763 100644 --- a/client/src/main/java/org/mvndaemon/mvnd/client/DaemonParameters.java +++ b/client/src/main/java/org/mvndaemon/mvnd/client/DaemonParameters.java @@ -21,16 +21,20 @@ package org.mvndaemon.mvnd.client; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.security.MessageDigest; import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HexFormat; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; @@ -450,21 +454,13 @@ public class DaemonParameters { if (env == Environment.MVND_EXT_CLASSPATH) { List<String> cp = parseExtClasspath(userHome()); return String.join(",", cp); - } else if (env == Environment.MVND_CORE_EXTENSIONS_FILE_PATH) { - try { - return resolveCoreExtensionFilePath(multiModuleProjectDirectory()); - } catch (IOException e) { - throw new RuntimeException("Unable to resolve core extension configuration file path", e); - } + } else if (env == Environment.MVND_CORE_EXTENSIONS_DISCRIMINATOR) { + return calculateCoreExtensionsDiscriminator(multiModuleProjectDirectory(), userHome(), mvndHome()); } else if (env == Environment.MVND_CORE_EXTENSIONS_EXCLUDE) { String exclusionsString = systemProperty(Environment.MVND_CORE_EXTENSIONS_EXCLUDE) .orDefault() .asString(); - if (exclusionsString != null) { - return exclusionsString; - } else { - return ""; - } + return Objects.requireNonNullElse(exclusionsString, ""); } else { return env.getDefault(); } @@ -482,15 +478,43 @@ public class DaemonParameters { return jars; } - private static String resolveCoreExtensionFilePath(Path multiModuleProjectDirectory) throws IOException { - if (multiModuleProjectDirectory == null) { - return ""; - } - Path extensionsFile = multiModuleProjectDirectory.resolve(EXTENSIONS_FILENAME); - if (!Files.exists(extensionsFile)) { - return ""; + private static String calculateCoreExtensionsDiscriminator( + Path multiModuleProjectDirectory, Path userHome, Path mvndHome) { + try { + Path projectExtensionsXml = multiModuleProjectDirectory + .resolve(".mvn") + .resolve("extensions.xml") + .toAbsolutePath() + .normalize(); + Path userExtensionsXml = userHome.resolve(".m2") + .resolve("extensions.xml") + .toAbsolutePath() + .normalize(); + Path installationExtensionsXml = mvndHome.resolve("mvn") + .resolve("conf") + .resolve("extensions.xml") + .toAbsolutePath() + .normalize(); + + String blob = ""; + if (Files.exists(projectExtensionsXml)) { + blob += projectExtensionsXml.toString(); + blob += Files.readString(projectExtensionsXml); + } + if (Files.exists(userExtensionsXml)) { + blob += userExtensionsXml.toString(); + blob += Files.readString(userExtensionsXml); + } + if (Files.exists(installationExtensionsXml)) { + blob += installationExtensionsXml.toString(); + blob += Files.readString(installationExtensionsXml); + } + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + digest.update(blob.getBytes(StandardCharsets.UTF_8)); + return HexFormat.of().formatHex(digest.digest()); + } catch (Exception e) { + throw new IllegalStateException("Cannot calculate core extensions discriminator", e); } - return extensionsFile.toAbsolutePath().toString(); } private static Properties loadProperties(Path path) { diff --git a/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java b/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java index 648914c4..110dc653 100644 --- a/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java +++ b/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java @@ -212,10 +212,13 @@ public enum Environment { */ MVND_EXT_CLASSPATH("mvnd.extClasspath", null, null, OptionType.STRING, Flags.DISCRIMINATING | Flags.INTERNAL), /** - * Internal option to specify the maven extension configuration file path to register. + * Internal option to hold the maven extension configuration files "discriminator" to discriminate among daemons. + * Value of this option is irrelevant and is unused on daemon side. The only purpose and requirement is that the value + * discriminate the daemon based on 3 extension file contents (project, user, installation), and if any file change, + * this option value should change as well. It should behave like a hash value calculated out of 3 file contents would. */ - MVND_CORE_EXTENSIONS_FILE_PATH( - "mvnd.coreExtensionFilePath", null, null, OptionType.STRING, Flags.DISCRIMINATING | Flags.INTERNAL), + MVND_CORE_EXTENSIONS_DISCRIMINATOR( + "mvnd.coreExtensionsDiscriminator", null, null, OptionType.STRING, Flags.DISCRIMINATING | Flags.INTERNAL), /** * Internal option to specify comma separated list of maven extension G:As to exclude (to not load them from * .mvn/extensions.xml). This option makes possible for example that a project that with vanilla Maven would diff --git a/daemon/src/main/java/org/apache/maven/cli/DaemonMavenParser.java b/daemon/src/main/java/org/apache/maven/cli/DaemonMavenParser.java index 75114140..f4f6848a 100644 --- a/daemon/src/main/java/org/apache/maven/cli/DaemonMavenParser.java +++ b/daemon/src/main/java/org/apache/maven/cli/DaemonMavenParser.java @@ -18,13 +18,7 @@ */ package org.apache.maven.cli; -import javax.xml.stream.XMLStreamException; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -35,7 +29,6 @@ import java.util.stream.Collectors; import org.apache.commons.cli.ParseException; import org.apache.maven.api.cli.extensions.CoreExtension; import org.apache.maven.api.cli.mvn.MavenOptions; -import org.apache.maven.cling.internal.extension.io.CoreExtensionsStaxReader; import org.apache.maven.cling.invoker.mvn.MavenParser; import org.mvndaemon.mvnd.common.Environment; @@ -57,34 +50,14 @@ public class DaemonMavenParser extends MavenParser { } @Override - protected List<CoreExtension> readCoreExtensionsDescriptor(LocalContext context) { - String coreExtensionsFilePath = Environment.MVND_CORE_EXTENSIONS_FILE_PATH.asString(); - if (!coreExtensionsFilePath.isEmpty()) { - try { - return readCoreExtensionsDescriptor(Path.of(coreExtensionsFilePath)); - } catch (Exception e) { - throw new RuntimeException(e); - } - } else { - return new ArrayList<>(); - } - } - - private List<CoreExtension> readCoreExtensionsDescriptor(Path extensionsFile) - throws IOException, XMLStreamException { - - CoreExtensionsStaxReader parser = new CoreExtensionsStaxReader(); - List<CoreExtension> extensions; - try (InputStream is = Files.newInputStream(extensionsFile)) { - extensions = parser.read(is).getExtensions(); - } - return filterCoreExtensions(extensions); + protected List<CoreExtension> readCoreExtensionsDescriptorFromFile(Path extensionsFile) { + return filterCoreExtensions(super.readCoreExtensionsDescriptorFromFile(extensionsFile)); } - private static List<CoreExtension> filterCoreExtensions(List<CoreExtension> coreExtensions) { + protected static List<CoreExtension> filterCoreExtensions(List<CoreExtension> coreExtensions) { String exclusionsString = Environment.MVND_CORE_EXTENSIONS_EXCLUDE.asString(); Set<String> exclusions = Arrays.stream(exclusionsString.split(",")) - .filter(e -> e != null && !e.trim().isEmpty()) + .filter(e -> !e.trim().isEmpty()) .collect(Collectors.toSet()); if (!exclusions.isEmpty()) { return coreExtensions.stream()