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()

Reply via email to