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"`