This is an automated email from the ASF dual-hosted git repository.

mbien pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new 0ab330adb9 [NETBEANS-5479] improve maven multithreaded execution 
detection.
     new 27ed405fe6 Merge pull request #5482 from asbachb/bugfix/5479
0ab330adb9 is described below

commit 0ab330adb9d07c7646354e4ea450ad4f41f1ea5f
Author: Benjamin Asbach <[email protected]>
AuthorDate: Sat Feb 18 13:20:13 2023 +0100

    [NETBEANS-5479] improve maven multithreaded execution detection.
    
    mvn is ST by default, mvnd is MT by default. Lets try to detect the
    execution mode a bit better by inspecting the command line parameters.
    
    MT modes can't use the event spy.
    
    contains minor performance improvement:
    
    try to get maven version by analyzing `maven-core.jar` file name.
    this is a lot faster than opening the jar, parsing and evaluating the
    properties file. Since the file name approach does not work for
    maven 2 the previous logic was kept.
    
    Co-authored-by: Michael Bien <[email protected]>
---
 .../maven/execute/MavenCommandLineExecutor.java    |  53 ++++++-
 .../maven/execute/cmd/ShellConstructor.java        |   4 +-
 .../modules/maven/options/MavenSettings.java       |  26 +++-
 .../MavenCommandParametersAnalyzerTest.java        | 132 ++++++++++++++++
 .../MavenDaemonCommandParametersAnalyzerTest.java  | 169 +++++++++++++++++++++
 5 files changed, 373 insertions(+), 11 deletions(-)

diff --git 
a/java/maven/src/org/netbeans/modules/maven/execute/MavenCommandLineExecutor.java
 
b/java/maven/src/org/netbeans/modules/maven/execute/MavenCommandLineExecutor.java
index 286b478664..99e500c34c 100644
--- 
a/java/maven/src/org/netbeans/modules/maven/execute/MavenCommandLineExecutor.java
+++ 
b/java/maven/src/org/netbeans/modules/maven/execute/MavenCommandLineExecutor.java
@@ -28,6 +28,7 @@ import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.nio.charset.Charset;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -149,6 +150,7 @@ public class MavenCommandLineExecutor extends 
AbstractMavenExecutor {
     private static final RequestProcessor UPDATE_INDEX_RP = new 
RequestProcessor(RunUtils.class.getName(), 5);
 
     private static final String ICON_MAVEN_PROJECT = 
"org/netbeans/modules/maven/resources/Maven2Icon.gif"; // NOI18N
+
     /**
      * Execute maven build in NetBeans execution engine.
      * Most callers should rather use {@link #run} as this variant does no 
(non-late-bound) prerequisite checks.
@@ -855,6 +857,11 @@ public class MavenCommandLineExecutor extends 
AbstractMavenExecutor {
         return version != null && version.startsWith("2");
     }
 
+    private boolean isMavenDaemon() {
+        File mvnHome = EmbedderFactory.getEffectiveMavenHome();
+        return MavenSettings.isMavenDaemon(Paths.get(mvnHome.getPath()));
+    }
+
     private void injectEventSpy(final BeanRunConfig clonedConfig) {
         //TEMP 
         String mavenPath = 
clonedConfig.getProperties().get(CosChecker.MAVENEXTCLASSPATH);
@@ -878,16 +885,48 @@ public class MavenCommandLineExecutor extends 
AbstractMavenExecutor {
     }
 
     private boolean isMultiThreaded(BeanRunConfig clonedConfig) {
-        String list = MavenSettings.getDefault().getDefaultOptions();
-        for (String s : clonedConfig.getGoals()) {
-            list = list + " " + s;
-        }
+
+        List<String> params = new ArrayList<>();
+        
params.addAll(Arrays.asList(MavenSettings.getDefault().getDefaultOptions().split("
 ")));
+        params.addAll(clonedConfig.getGoals());
         if (clonedConfig.getPreExecution() != null) {
-            for (String s : clonedConfig.getPreExecution().getGoals()) {
-                list = list + " " + s;
+            params.addAll(clonedConfig.getPreExecution().getGoals());
+        }
+
+        return isMavenDaemon() ? isMultiThreadedMvnd(params)
+                               : isMultiThreadedMaven(params);
+    }
+
+    // mvnd is MT by default
+    static boolean isMultiThreadedMvnd(List<String> params) {
+        for (int i = 0; i < params.size(); i++) {
+            String p = params.get(i);
+            if (p.equals("-1") || p.equals("--serial") || 
p.equals("-Dmvnd.serial")) { // "behave like standard maven" mode
+                return false;
+            }
+            if (i + 1 < params.size() && (p.equals("-T") || 
p.equals("--threads"))) {
+                if (params.get(i+1).equals("1")) {
+                    return false;
+                }
+            }
+            try {
+                if (p.startsWith("-Dmvnd.threads=") && 
Integer.parseInt(p.substring(15)) == 1)  {
+                    return false;
+                }
+            } catch (NumberFormatException ignored) {} 
+        }
+        return true;
+    }
+
+    // mvn is ST by default
+    static boolean isMultiThreadedMaven(List<String> params) {
+        for (int i = 0; i < params.size() - 1; i++) {
+            String p = params.get(i);
+            if ((p.equals("-T") || p.equals("--threads")) && 
!params.get(i+1).equals("1")) {
+                return true;
             }
         }
-        return list.contains("-T") || list.contains("--threads");
+        return false;
     }
 
     private File guessBestMaven(RunConfig clonedConfig, InputOutput ioput) {
diff --git 
a/java/maven/src/org/netbeans/modules/maven/execute/cmd/ShellConstructor.java 
b/java/maven/src/org/netbeans/modules/maven/execute/cmd/ShellConstructor.java
index d1d661585f..5433e7f413 100644
--- 
a/java/maven/src/org/netbeans/modules/maven/execute/cmd/ShellConstructor.java
+++ 
b/java/maven/src/org/netbeans/modules/maven/execute/cmd/ShellConstructor.java
@@ -20,7 +20,6 @@
 package org.netbeans.modules.maven.execute.cmd;
 
 import java.io.File;
-import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
@@ -44,8 +43,7 @@ public class ShellConstructor implements Constructor {
     public List<String> construct() {
 
         // use mvnd if its the home of a daemon
-        String mavenDaemonSuffixDetection = Utilities.isWindows() ? ".exe" : 
"";
-        String ex = Files.exists(Paths.get(mavenHome.getPath(), "bin", "mvnd" 
+ mavenDaemonSuffixDetection)) ? "mvnd" : "mvn"; //NOI18N
+        String ex = 
MavenSettings.isMavenDaemon(Paths.get(mavenHome.getPath())) ? "mvnd" : "mvn"; 
//NOI18N
 
         List<String> command = new ArrayList<>();
 
diff --git 
a/java/maven/src/org/netbeans/modules/maven/options/MavenSettings.java 
b/java/maven/src/org/netbeans/modules/maven/options/MavenSettings.java
index bda5cbabf2..850fd76708 100644
--- a/java/maven/src/org/netbeans/modules/maven/options/MavenSettings.java
+++ b/java/maven/src/org/netbeans/modules/maven/options/MavenSettings.java
@@ -31,12 +31,14 @@ import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 import java.util.Properties;
 import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.prefs.BackingStoreException;
 import java.util.prefs.Preferences;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import org.apache.maven.execution.MavenExecutionRequest;
@@ -48,6 +50,7 @@ import org.openide.filesystems.FileUtil;
 import org.openide.filesystems.URLMapper;
 import org.openide.util.NbBundle;
 import org.openide.util.NbPreferences;
+import org.openide.util.Utilities;
 import org.openide.util.WeakSet;
 
 /**
@@ -87,6 +90,8 @@ public final class MavenSettings  {
     private static final String PROP_USE_REGISTRY = "usePluginRegistry"; 
//NOI18N
     public static final String PROP_NETWORK_PROXY = "networkProxy";
       
+    private static final Pattern MAVEN_CORE_JAR_PATTERN = 
Pattern.compile("maven-core-(\\d+\\.\\d+\\.\\d+)\\.jar");  // NOI18N
+
     private static final MavenSettings INSTANCE = new MavenSettings();
     
     private final Set<PropertyChangeListener> listeners = new WeakSet<>();
@@ -471,7 +476,6 @@ public final class MavenSettings  {
     }
     
     public static @CheckForNull String getCommandLineMavenVersion(File 
mavenHome) {
-
         Path lib = Paths.get(mavenHome.getPath(), "lib");        // mvn layout 
 // NOI18N
         if (!Files.exists(lib)) {
             lib = Paths.get(mavenHome.getPath(), "mvn", "lib");  // mvnd 
layout // NOI18N
@@ -480,6 +484,20 @@ public final class MavenSettings  {
             }
         }
 
+        // try to resolve maven version by checking maven-core jar name
+        try (Stream<String> mavenCoreVersions = Files.list(lib)
+                .map(file -> file.getFileName().toString())
+                .filter(file -> file.startsWith("maven-core")) // NOI18N
+                .map(file -> MAVEN_CORE_JAR_PATTERN.matcher(file))
+                .filter(matcher -> matcher.matches())
+                .map(matcher -> matcher.group(1))) {
+            Optional<String> mavenCoreVersion = mavenCoreVersions.findFirst();
+            if (mavenCoreVersion.isPresent()) {
+                return mavenCoreVersion.get();
+            }
+        } catch (IOException ignored) {}
+
+        // try to resolve maven version by parsing pom.properties
         try {
             try (Stream<Path> jars = Files.list(lib).filter(file -> 
file.toString().endsWith(".jar"))) {  // NOI18N
                 for (Path jar : jars.collect(Collectors.toList())) {
@@ -500,6 +518,12 @@ public final class MavenSettings  {
         return null;
     }
 
+    public static boolean isMavenDaemon(Path mavenHome) {
+        String mvndExecutableName = Utilities.isWindows() ? "mvnd.exe" : 
"mvnd";
+
+        return 
Files.exists(mavenHome.resolve("bin").resolve(mvndExecutableName));
+    }
+
     private static List<String> searchMavenRuntimes(String[] paths, boolean 
stopOnFirstValid) {
         List<String> runtimes = new ArrayList<>();
         for (String path : paths) {
diff --git 
a/java/maven/test/unit/src/org/netbeans/modules/maven/execute/MavenCommandParametersAnalyzerTest.java
 
b/java/maven/test/unit/src/org/netbeans/modules/maven/execute/MavenCommandParametersAnalyzerTest.java
new file mode 100644
index 0000000000..e7f7ef4947
--- /dev/null
+++ 
b/java/maven/test/unit/src/org/netbeans/modules/maven/execute/MavenCommandParametersAnalyzerTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+package org.netbeans.modules.maven.execute;
+
+import java.util.Arrays;
+
+import static junit.framework.TestCase.assertFalse;
+import static junit.framework.TestCase.assertTrue;
+
+import org.junit.Test;
+
+/**
+ *
+ * @author Benjamin Asbach ([email protected])
+ */
+public class MavenCommandParametersAnalyzerTest {
+
+    @Test
+    public void defaultIsSingleThreaded() {
+        assertFalse(isMultiThreadedMaven(""));
+    }
+ 
+    @Test
+    public void validateMultiThreaded1() {
+        assertTrue(isMultiThreadedMaven("-T 10"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded2() {
+        assertTrue(isMultiThreadedMaven("-T 2"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded3() {
+        assertTrue(isMultiThreadedMaven("-Dmaven.test.skip=true -T 10"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded4() {
+        assertTrue(isMultiThreadedMaven("-Dmaven.test.skip=true -T 2"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded5() {
+        assertTrue(isMultiThreadedMaven("-Dmaven.test.skip=true -T 10 
-Dmaven.test.skip=true "));
+    }
+ 
+    @Test
+    public void validateMultiThreaded6() {
+        assertTrue(isMultiThreadedMaven("-Dmaven.test.skip=true -T 2 
-Dmaven.test.skip=true "));
+    }
+ 
+    @Test
+    public void validateMultiThreaded7() {
+        assertTrue(isMultiThreadedMaven("-T 10 -Dmaven.test.skip=true"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded8() {
+        assertTrue(isMultiThreadedMaven("-T 2 -Dmaven.test.skip=true"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded9() {
+        assertTrue(isMultiThreadedMaven("--threads 10"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded10() {
+        assertTrue(isMultiThreadedMaven("--threads 2"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded11() {
+        assertTrue(isMultiThreadedMaven("-Dmaven.test.skip=true --threads 
10"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded12() {
+        assertTrue(isMultiThreadedMaven("-Dmaven.test.skip=true --threads 2"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded13() {
+        assertTrue(isMultiThreadedMaven("-Dmaven.test.skip=true --threads 10 
-Dmaven.test.skip=true "));
+    }
+ 
+    @Test
+    public void validateMultiThreaded14() {
+        assertTrue(isMultiThreadedMaven("-Dmaven.test.skip=true --threads 2 
-Dmaven.test.skip=true "));
+    }
+ 
+    @Test
+    public void validateMultiThreaded15() {
+        assertTrue(isMultiThreadedMaven("--threads 10 
-Dmaven.test.skip=true"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded16() {
+        assertTrue(isMultiThreadedMaven("--threads 2 -Dmaven.test.skip=true"));
+    }
+
+    @Test
+    public void validateSingleThreaded1() {
+        assertFalse(isMultiThreadedMaven("--threads 1"));
+    }
+
+    @Test
+    public void validateSingleThreaded2() {
+        assertFalse(isMultiThreadedMaven("-T 1"));
+    }
+
+    private boolean isMultiThreadedMaven(String params) {
+        return 
MavenCommandLineExecutor.isMultiThreadedMaven(Arrays.asList(params.split(" ")));
+    }
+}
diff --git 
a/java/maven/test/unit/src/org/netbeans/modules/maven/execute/MavenDaemonCommandParametersAnalyzerTest.java
 
b/java/maven/test/unit/src/org/netbeans/modules/maven/execute/MavenDaemonCommandParametersAnalyzerTest.java
new file mode 100644
index 0000000000..edeeb9c933
--- /dev/null
+++ 
b/java/maven/test/unit/src/org/netbeans/modules/maven/execute/MavenDaemonCommandParametersAnalyzerTest.java
@@ -0,0 +1,169 @@
+/*
+ * 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.
+ */
+package org.netbeans.modules.maven.execute;
+
+import java.util.Arrays;
+
+import static junit.framework.TestCase.assertFalse;
+import static junit.framework.TestCase.assertTrue;
+
+import org.junit.Test;
+
+/**
+ *
+ * @author Benjamin Asbach ([email protected])
+ */
+public class MavenDaemonCommandParametersAnalyzerTest {
+
+    @Test
+    public void defaultIsSingleThreaded() {
+        assertTrue(checkisMultiThreadedMvnd(""));
+    }
+
+    @Test
+    public void validateMultiThreaded1() {
+        assertTrue(checkisMultiThreadedMvnd("-T 10"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded3() {
+        assertTrue(checkisMultiThreadedMvnd("-Dmaven.test.skip=true -T 10"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded5() {
+        assertTrue(checkisMultiThreadedMvnd("-Dmaven.test.skip=true -T 10 
-Dmaven.test.skip=true "));
+    }
+ 
+    @Test
+    public void validateMultiThreaded7() {
+        assertTrue(checkisMultiThreadedMvnd("-T 10 -Dmaven.test.skip=true"));
+    }
+
+
+    @Test
+    public void validateMultiThreaded2() {
+        assertTrue(checkisMultiThreadedMvnd("-T 2"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded4() {
+        assertTrue(checkisMultiThreadedMvnd("-Dmaven.test.skip=true -T 2"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded6() {
+        assertTrue(checkisMultiThreadedMvnd("-Dmaven.test.skip=true -T 2 
-Dmaven.test.skip=true "));
+    }
+ 
+    @Test
+    public void validateMultiThreaded8() {
+        assertTrue(checkisMultiThreadedMvnd("-T 2 -Dmaven.test.skip=true"));
+    }
+
+ 
+    @Test
+    public void validateMultiThreaded9() {
+        assertTrue(checkisMultiThreadedMvnd("--threads 10"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded11() {
+        assertTrue(checkisMultiThreadedMvnd("-Dmaven.test.skip=true --threads 
10"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded13() {
+        assertTrue(checkisMultiThreadedMvnd("-Dmaven.test.skip=true --threads 
10 -Dmaven.test.skip=true "));
+    }
+ 
+    @Test
+    public void validateMultiThreaded15() {
+        assertTrue(checkisMultiThreadedMvnd("--threads 10 
-Dmaven.test.skip=true"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded10() {
+        assertTrue(checkisMultiThreadedMvnd("--threads 2"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded12() {
+        assertTrue(checkisMultiThreadedMvnd("-Dmaven.test.skip=true --threads 
2"));
+    }
+ 
+    @Test
+    public void validateMultiThreaded14() {
+        assertTrue(checkisMultiThreadedMvnd("-Dmaven.test.skip=true --threads 
2 -Dmaven.test.skip=true "));
+    }
+ 
+    @Test
+    public void validateMultiThreaded16() {
+        assertTrue(checkisMultiThreadedMvnd("--threads 2 
-Dmaven.test.skip=true"));
+    }
+
+    @Test
+    public void validateMultiThreaded17() {
+        assertTrue(checkisMultiThreadedMvnd("-Dmvnd.threads=2 
-Dmaven.test.skip=true"));
+    }
+
+    @Test
+    public void validateSingleThreaded1() {
+        assertFalse(checkisMultiThreadedMvnd("--threads 1"));
+    }
+
+    @Test
+    public void validateSingleThreaded3() {
+        assertFalse(checkisMultiThreadedMvnd("-Dmaven.test.skip=true --threads 
1"));
+    }
+
+    @Test
+    public void validateSingleThreaded5() {
+        assertFalse(checkisMultiThreadedMvnd("--threads 1 
-Dmaven.test.skip=true"));
+    }
+
+    @Test
+    public void validateSingleThreaded2() {
+        assertFalse(checkisMultiThreadedMvnd("-T 1"));
+    }
+
+    @Test
+    public void validateSingleThreaded4() {
+        assertFalse(checkisMultiThreadedMvnd("-Dmaven.test.skip=true -T 1"));
+    }
+
+    @Test
+    public void validateSingleThreaded6() {
+        assertFalse(checkisMultiThreadedMvnd("-T 1 -Dmaven.test.skip=true"));
+    }
+
+    @Test
+    public void validateSingleThreaded7() {
+        assertFalse(checkisMultiThreadedMvnd("-Dmvnd.threads=1"));
+    }
+
+    @Test
+    public void validateSingleThreaded8() {
+        assertTrue(checkisMultiThreadedMvnd("-Dmvnd.threads=foo 
-Dmaven.test.skip=true"));
+    }
+
+    private boolean checkisMultiThreadedMvnd(String params) {
+        return 
MavenCommandLineExecutor.isMultiThreadedMvnd(Arrays.asList(params.split(" ")));
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to