You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by gn...@apache.org on 2026/10/14 08:03:07 UTC

(maven) branch master updated: Verify the cygpath on the PATH converts to usable Windows paths

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 4d7b67b552 Verify the cygpath on the PATH converts to usable Windows paths
4d7b67b552 is described below

commit 4d7b67b5529a1ab0d5ec3292cc9336b5ee67bb28
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Wed Oct 14 10:02:59 2026 +0200

    Verify the cygpath on the PATH converts to usable Windows paths
    
    Port of #13429 to `master`.
    
    A `cygpath(1)` from an unrelated POSIX emulation layer (e.g. Anaconda) can be
    found on the PATH first. It re-roots every POSIX path under its own prefix,
    causing a bare `ClassNotFoundException` at launch. This adds a sanity-probe:
    convert the current directory with the `cygpath` found, and require its Windows
    form to exist on disk. On failure, warn and fall back to POSIX paths — same
    posture as the missing-cygpath case introduced in #12567.
    
    - Add cygpath sanity-check: verify the Windows path returned by cygpath exists on disk
    - On failure, warn and fall back to POSIX paths
    - Add test coverage in `test-mvn-path-conversion.sh` for the bogus-cygpath scenario
    
    Closes #13414
---
 apache-maven/src/assembly/maven/bin/mvn            | 20 ++++++
 .../src/test/scripts/test-mvn-path-conversion.sh   | 78 ++++++++++++++++++++++
 2 files changed, 98 insertions(+)

diff --git a/apache-maven/src/assembly/maven/bin/mvn b/apache-maven/src/assembly/maven/bin/mvn
index 8f9cc91512..58264f5c57 100755
--- a/apache-maven/src/assembly/maven/bin/mvn
+++ b/apache-maven/src/assembly/maven/bin/mvn
@@ -77,6 +77,26 @@ if $cygwin || $mingw ; then
   fi
 fi
 
+# A cygpath(1) from an unrelated POSIX emulation layer (e.g. the one shipped in
+# an Anaconda installation) can be found on the PATH first. It re-roots every
+# POSIX path under its own installation prefix, so all converted values point to
+# non-existing directories and the JVM dies with a bare ClassNotFoundException.
+# cygpath can convert relative paths too, but the current directory is the only
+# path that is known to exist at this point: verify that its Windows form can be
+# found on disk before trusting any of the later conversions.
+if $cygwin || $mingw ; then
+  _cygpath_bin=`( \unset -f command; \command -v cygpath )` || _cygpath_bin=
+  _probe_win=`cygpath --windows "$PWD"` || _probe_win=
+  if [ -z "$_probe_win" ] || [ ! -d "$_probe_win" ] ; then
+    printf '%s\n' "Warning: the cygpath found on the PATH (\"$_cygpath_bin\") does not convert paths to" >&2
+    printf '%s\n' "usable Windows paths (\"$PWD\" converts to \"$_probe_win\", which does not exist)," >&2
+    printf '%s\n' "so Apache Maven cannot convert paths to the Windows format." >&2
+    printf '%s\n' "Some plugins may misbehave when they receive POSIX paths." >&2
+    cygwin=false
+    mingw=false
+  fi
+fi
+
 ## resolve links - $0 may be a link to Maven's home
 PRG="$0"
 
diff --git a/apache-maven/src/test/scripts/test-mvn-path-conversion.sh b/apache-maven/src/test/scripts/test-mvn-path-conversion.sh
index 81207c60b8..e9ee4255c8 100644
--- a/apache-maven/src/test/scripts/test-mvn-path-conversion.sh
+++ b/apache-maven/src/test/scripts/test-mvn-path-conversion.sh
@@ -178,6 +178,53 @@ for stub in uname dirname java; do
   chmod +x "$nocygpath_dir/$stub"
 done
 
+# A third stub set whose cygpath re-roots every POSIX path under its own
+# installation prefix, like the cygpath shipped inside an Anaconda installation
+# does (issue #13414). The launcher must detect that the Windows form does not
+# exist on disk, warn, and fall back to unconverted POSIX paths.
+lying_dir="$work_dir/stubs-lying-cygpath"
+mkdir -p "$lying_dir"
+for stub in uname dirname java; do
+  cp "$stub_dir/$stub" "$lying_dir/$stub"
+  chmod +x "$lying_dir/$stub"
+done
+
+cat > "$lying_dir/cygpath" <<'LYING'
+#!/bin/sh
+# cygpath(1) stub re-rooting every POSIX path under its own prefix, like the
+# Anaconda-shipped cygpath that caused issue #13414.
+for arg in "$@"; do
+  case "$arg" in
+    --*) ;;
+    *) path="$arg" ;;
+  esac
+done
+
+replace() {
+  text="$1"; needle="$2"; value="$3"; out=""
+  while :; do
+    case "$text" in
+      *"$needle"*)
+        out="$out${text%%"$needle"*}$value"
+        text="${text#*"$needle"}"
+        ;;
+      *) break ;;
+    esac
+  done
+  printf '%s' "$out$text"
+}
+
+case " $* " in
+  *" --windows "*)
+    printf 'C:\Anaconda\Library\%s\n' "`replace "$path" '/' '\'`"
+    ;;
+  *)
+    printf '%s\n' "$path"
+    ;;
+esac
+LYING
+chmod +x "$lying_dir/cygpath"
+
 # A jvm.config referencing the project base directory, to assert that the value
 # handed over to the JVM configuration is converted as well.
 echo '-Xmx512m -Dtest.basedir=${MAVEN_PROJECTBASEDIR}' > "$project_dir/.mvn/jvm.config"
@@ -223,6 +270,16 @@ to_windows() {
   printf 'C:%s' "$out$text"
 }
 
+# bin/mvn verifies that the Windows form of the current directory exists on
+# disk before trusting the cygpath output. The stubbed cygpath produces
+# C:-prefixed paths, which exist on Windows only. POSIX filesystems accept
+# them literally (backslashes and colons are ordinary characters), so create
+# the directory here to let the verification pass with the stub as well. On
+# Windows creating it fails because the real directory exists: fine.
+# mkdir -p: on Windows the argument is a real multi-component path whose
+# parents may not exist yet; on POSIX it is a single oddly-named directory.
+( cd "$project_dir/module" && mkdir -p "`to_windows "$project_dir/module"`" 2>/dev/null || true )
+
 # contains <haystack> <needle>
 # Plain substring check. A case/glob comparison cannot be used, the haystack
 # holds Windows paths and backslashes are escape characters in glob patterns.
@@ -311,6 +368,27 @@ assert_contains "missing cygpath: maven.home falls back to a POSIX path" "$outpu
 assert_not_contains "missing cygpath: no empty maven.home is passed" "$output" \
   "[-Dmaven.home=]"
 
+# A cygpath from a foreign emulation layer must be detected: the conversion is
+# skipped, the paths stay in their POSIX form, and warnings explain why.
+output=`run_mvn MINGW64_NT-10.0 "$lying_dir"`
+assert_contains "foreign cygpath: multiModuleProjectDirectory falls back to a POSIX path" "$output" \
+  "[-Dmaven.multiModuleProjectDirectory=$project_dir]"
+assert_contains "foreign cygpath: maven.home falls back to a POSIX path" "$output" \
+  "[-Dmaven.home=$maven_home]"
+assert_not_contains "foreign cygpath: no empty maven.home is passed" "$output" \
+  "[-Dmaven.home=]"
+
+# ... and the warnings name the offending cygpath and the bogus conversion.
+warn_output=`( cd "$project_dir/module" &&
+  FAKE_UNAME="MINGW64_NT-10.0" PATH="$lying_dir" JAVA_HOME= MAVEN_SKIP_RC=1 \
+    "$sh_bin" "$maven_home/bin/mvn" verify 2>&1 )`
+assert_contains "foreign cygpath: warning names the offending cygpath" "$warn_output" \
+  "does not convert paths to"
+assert_contains "foreign cygpath: warning shows the bogus Windows form" "$warn_output" \
+  "which does not exist"
+assert_contains "foreign cygpath: warning names the discovered cygpath" "$warn_output" \
+  "stubs-lying-cygpath/cygpath"
+
 # The debug log must reproduce the Windows paths verbatim. echo expands
 # backslash escapes in dash and friends, turning C:\tmp into C:<tab>mp.
 debug_output=`run_mvn_debug MSYS_NT-10.0 "$stub_dir"`