gnodet-bot commented on code in PR #13491:
URL: https://github.com/apache/maven/pull/13491#discussion_r4268134736


##########
apache-maven/src/assembly/maven/bin/mvn:
##########
@@ -445,20 +445,38 @@ fi
 if [ -n "$MAVEN_DEBUG_SCRIPT" ]; then
   printf '[DEBUG] Final MAVEN_OPTS: %s\n' "$MAVEN_OPTS" >&2
 fi
-LAUNCHER_JAR=`echo "$MAVEN_HOME"/boot/plexus-classworlds-*.jar`
+LAUNCHER_JAR=""
+for _jar in "$MAVEN_HOME"/boot/*.jar; do
+  [ -f "$_jar" ] && LAUNCHER_JAR="${LAUNCHER_JAR:+$LAUNCHER_JAR:}$_jar"
+done
 LAUNCHER_CLASS=org.codehaus.plexus.classworlds.launcher.Launcher
 JLINE_NATIVE_PATH="$MAVEN_HOME/lib/jline-native"
+MODULES_DIR="$MAVEN_HOME/lib/modules"
+
+# Module-path and native access flags require a JDK that can read the module 
jars.
+# The probe includes --module-path so it fails on JDKs that cannot read the 
module descriptors.
+USE_MODULE_PATH=false
+if "$JAVACMD" --module-path "$MODULES_DIR" --add-modules ALL-MODULE-PATH 
--enable-native-access=org.jline.terminal.ffm -version >/dev/null 2>&1; then
+  USE_MODULE_PATH=true
+fi

Review Comment:
   ⚠️ **Cygwin/MinGW regression: probe runs before path conversion**
   
   The `USE_MODULE_PATH` probe (lines 456–461) runs before the cygwin path 
conversion block that converts `MODULES_DIR` to Windows format (line 474). On 
Cygwin and MinGW, `MODULES_DIR` is still `/cygdrive/c/.../lib/modules` (a POSIX 
path) at probe time; `java.exe` (a native Windows binary) cannot parse it, so 
the probe always exits non-zero → `USE_MODULE_PATH=false` → 
`MAVEN_MODULE_OPTS=""` → **no `--enable-native-access` at all**.
   
   The old behaviour hardcoded `--enable-native-access=ALL-UNNAMED` 
unconditionally. The new behaviour silently drops it on Cygwin/MinGW, breaking 
JLine native terminal support.
   
   Fix: move the probe block to **after** the cygwin conversion block (after 
line 475), where `MODULES_DIR` is already in the correct Windows format and 
`MAVEN_MODULE_OPTS` is set:
   
   ```bash
   MAVEN_MODULE_OPTS=""
   # Module-path and native access flags require a JDK that can read the module 
jars.
   # The probe includes --module-path so it fails on JDKs that cannot read the 
module descriptors.
   USE_MODULE_PATH=false
   if "$JAVACMD" --module-path "$MODULES_DIR" --add-modules ALL-MODULE-PATH 
--enable-native-access=org.jline.terminal.ffm -version >/dev/null 2>&1; then
     MAVEN_MODULE_OPTS="--module-path \"$MODULES_DIR\" --add-modules 
ALL-MODULE-PATH --enable-native-access=org.jline.terminal.ffm,org.jline.nativ"
   fi
   ```
   
   (i.e., fold the probe directly into the `MAVEN_MODULE_OPTS` assignment and 
move the whole block after line 475)



##########
compat/maven-embedder/src/main/java/org/apache/maven/cli/CliRequest.java:
##########
@@ -23,9 +23,9 @@
 import java.util.Properties;
 
 import org.apache.commons.cli.CommandLine;
+import org.apache.maven.api.classworlds.ClassWorld;

Review Comment:
   ⚠️ **Binary-incompatible change in the compat layer**
   
   The `classWorld` field's declared type changes from 
`org.codehaus.plexus.classworlds.ClassWorld` to 
`org.apache.maven.api.classworlds.ClassWorld` at the bytecode level (only the 
import is changed here, but the field descriptor in the class file changes). 
This is a binary-incompatible change for any existing embedder that accesses 
`CliRequest.classWorld` directly — they'll get a `NoSuchFieldError` or 
`ClassCastException` at runtime without recompilation.
   
   The compat-layer convention is explicit: no behaviour changes in 
`compat/maven-embedder` unless the same change is ported to Maven 3.x. 
`CliRequest` is `@Deprecated`, but it's still a public field used by external 
embedders (IDEs, build tools, Maven wrapper implementations). If the intent is 
to migrate embedders to the new API type, this needs a release note and ideally 
a `@deprecated` field-level Javadoc pointing to the replacement.



##########
apache-maven/src/assembly/maven/bin/m2.conf:
##########
@@ -29,3 +31,4 @@ optionally ${user.home}/.m2/ext/*.jar
 optionally ${maven.home}/lib/ext/*.jar
 load       ${maven.home}/lib/maven-*.jar
 load       ${maven.home}/lib/*.jar
+load       ${maven.home}/lib/modules/*.jar

Review Comment:
   ❓ **Is the `load lib/modules/*.jar` intentional alongside `module 
lib/modules/*.jar`?**
   
   JLine JARs appear in both directives:
   - Line 24: `module ${maven.home}/lib/modules/*.jar` → deferred for 
`createModuleLayer()` → loaded into a child `ModuleLayer`
   - Line 34: `load ${maven.home}/lib/modules/*.jar` → added directly to the 
`plexus.core` realm's classpath
   
   After `createModuleLayer()` runs, `plexus.core`'s parent ClassLoader is 
retroactively updated to the ModuleLayer loader. With the default 
`ParentFirstStrategy`, the parent (module loader) is checked first, so the 
classpath entries are effectively shadowed — no functional duplication. However 
with `SelfFirstStrategy`, the realm loads JLine from its own classpath (a 
different `ClassLoader` instance than the module loader), creating class 
identity mismatches if JLine objects cross realm boundaries.
   
   If the `load` line is there only as a classpath fallback (for when the 
module probe fails), the existing `addModulePathsToClasspath()` in 
`Configurator` already handles that case. Please clarify: is the `load` 
directive intentional, or is it a duplicate that should be removed?



##########
compat/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java:
##########
@@ -285,7 +285,7 @@ public int doMain(String[] args, String workingDirectory, 
PrintStream stdout, Pr
         final Set<String> realms;
         if (classWorld != null) {
             realms = new HashSet<>();
-            for (ClassRealm realm : classWorld.getRealms()) {
+            for (ClassRealm realm : 
((org.codehaus.plexus.classworlds.ClassWorld) classWorld).getRealms()) {

Review Comment:
   ⚠️ **Repeated downcasts from API type to impl type in compat layer**
   
   This file now casts `ClassWorld` (declared as 
`org.apache.maven.api.classworlds.ClassWorld` from `CliRequest.classWorld`) 
back down to `org.codehaus.plexus.classworlds.ClassWorld` to access methods 
like `getRealms()` that don't exist on the API interface. The same pattern 
repeats at lines 328, 766, 781, 782, 824, 899, 900, 966, 967.
   
   These casts will work at runtime (the implementation IS-A API), but this 
pattern signals an incomplete API design: if `getRealms()` and 
`setParentRealm()` are needed in the compat layer, they should be part of 
`org.apache.maven.api.classworlds.ClassWorld`/`ClassRealm`. Alternatively, keep 
`CliRequest.classWorld` as the plexus implementation type (avoid the import 
swap in `CliRequest.java`) and only use the API type in new code.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to