From 5842bfda67a855b6a8191c4d1616fcd2dbe9527e Mon Sep 17 00:00:00 2001 From: Aman Sharma Date: Thu, 25 Nov 2021 11:06:44 +0100 Subject: [PATCH] fix: lookup absolute path to maven executable (#4298) Co-authored-by: Martin Wittlinger --- .../java/spoon/support/compiler/SpoonPom.java | 34 +++++++++++-------- src/test/java/spoon/MavenLauncherTest.java | 13 ++++--- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/main/java/spoon/support/compiler/SpoonPom.java b/src/main/java/spoon/support/compiler/SpoonPom.java index e5b7758f4c7..d95bfeabe19 100644 --- a/src/main/java/spoon/support/compiler/SpoonPom.java +++ b/src/main/java/spoon/support/compiler/SpoonPom.java @@ -519,18 +519,12 @@ private static String[] readClassPath(File... classPathFiles) throws IOException /** * Try to guess Maven home when none is provided. * @return the path toward maven install on the local machine. + * @throws SpoonException if path to maven executable is wrong, process is interrupted, or maven home could not be + * found. */ public static String guessMavenHome() { - String mvnHome = null; try { - String[] cmd; - if (System.getProperty("os.name").contains("Windows")) { - cmd = new String[]{"mvn.cmd", "-version"}; - } else if (System.getProperty("os.name").contains("Mac")) { - cmd = new String[]{"sh", "-c", "mvn -version"}; - } else { - cmd = new String[]{"mvn", "-version"}; - } + String[] cmd = new String[]{getPathToMavenExecutable(), "-version"}; Process p = Runtime.getRuntime().exec(cmd); try (BufferedReader output = new BufferedReader(new InputStreamReader(p.getInputStream()))) { String line; @@ -541,7 +535,6 @@ public static String guessMavenHome() { } } } - p.waitFor(); } catch (IOException e) { throw new SpoonException("Maven home detection has failed."); @@ -549,7 +542,23 @@ public static String guessMavenHome() { Thread.currentThread().interrupt(); throw new SpoonException("Maven home detection was interrupted."); } - return mvnHome; + throw new SpoonException("Couldn't find path to maven home."); + } + + private static String getPathToMavenExecutable() { + String executableName; + if (System.getProperty("os.name").contains("Windows")) { + executableName = "mvn.cmd"; + } else { + executableName = "mvn"; + } + for (String dirname : System.getenv("PATH").split(File.pathSeparator)) { + File file = new File(dirname, executableName); + if (file.isFile() && file.canExecute()) { + return file.getAbsolutePath(); + } + } + throw new SpoonException("Maven executable does not exist on PATH."); } /** @@ -564,9 +573,6 @@ public static String guessMavenHome() { public String[] buildClassPath(String mvnHome, MavenLauncher.SOURCE_TYPE sourceType, Logger LOGGER, boolean forceRefresh) { if (mvnHome == null) { mvnHome = guessMavenHome(); - if (mvnHome == null) { - throw new SpoonException("M2_HOME must be initialized to use this MavenLauncher constructor."); - } } generateClassPathFile(new File(mvnHome), sourceType, LOGGER, forceRefresh); diff --git a/src/test/java/spoon/MavenLauncherTest.java b/src/test/java/spoon/MavenLauncherTest.java index a00d7a5e48b..0f381503504 100644 --- a/src/test/java/spoon/MavenLauncherTest.java +++ b/src/test/java/spoon/MavenLauncherTest.java @@ -208,12 +208,11 @@ public void mavenLauncherTestMultiModulesAndVariables() { } @Test - public void testGuessMavenHome() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - Method method = SpoonPom.class.getDeclaredMethod("guessMavenHome", new Class[]{}); - method.setAccessible(true); - String mvnHome = (String) method.invoke(null, new Object[]{}); - File mvnDir = new File(mvnHome); - assertTrue(mvnDir.exists()); - assertTrue(mvnDir.isDirectory()); + public void testGuessMavenHome() { + // contract: it should correctly fetch path to maven home + String pathToMavenHome = SpoonPom.guessMavenHome(); + File mavenHome = new File(pathToMavenHome); + assertTrue(mavenHome.exists()); + assertTrue(mavenHome.isDirectory()); } }