Skip to content

Conversation

gnodet
Copy link
Owner

@gnodet gnodet commented Aug 9, 2025

Overview

This PR implements clean JPMS module support for JLine native access, moving away from --enable-native-access=ALL-UNNAMED to specific module-based permissions.

Key Changes

1. Updated Launcher Scripts

  • Modified mvn and mvn.cmd to use:
    • --module-path pointing to modules/ directory
    • --add-modules org.jline.nativ to ensure proper module loading
    • --enable-native-access=org.jline.nativ for targeted permissions

2. Created Modules Directory

  • Added modules/ directory in distribution assembly
  • Moved JLine JARs from lib/ to modules/ for proper JPMS handling:
    • jline-native, jline-terminal-jni, jline-terminal
    • jline-reader, jline-style, jline-builtins
    • jline-console, jline-console-ui, jansi-core

3. Updated Dependencies

  • Replaced jline-terminal-ffm with jline-native in apache-maven POM
  • Maintains existing native library extraction functionality

4. Enhanced Classworlds Configuration

  • Updated m2.conf to load JARs from both lib/ and modules/ directories
  • Ensures JLine classes are available on classpath for compatibility

Why Separate Modules Directory?

🚨 Critical JPMS Insight: Cannot use lib/ directory as module path because multiple Maven JARs export the same packages, causing module resolution conflicts.

Example conflict discovered during testing:

Error: Modules maven.core and maven.artifact export package 
org.apache.maven.artifact.resolver.filter to module maven.api.metadata

JPMS requires that only one module can export a package. Maven's lib/ directory contains many JARs with overlapping package exports, making it unsuitable as a module path.

Solution: Separate modules/ directory containing only JLine JARs avoids conflicts while providing clean JPMS module resolution.

Benefits

Enhanced Security: Native access limited to specific org.jline.nativ module instead of ALL-UNNAMED

Proper JPMS Support: JLine modules are properly loaded on module path without conflicts

Clean Architecture: Separates JPMS modules from regular classpath dependencies

Backward Compatibility: Maintains all existing Maven functionality

Foundation for Future: Provides clean foundation for broader JPMS migration

Technical Details

  • Module Loading: Uses --add-modules to ensure JLine modules are in the resolved module graph
  • Dual Loading: JLine JARs are on both module path and classpath for compatibility with Maven's classworlds
  • Native Access: Only org.jline.nativ module gets native access permissions
  • Conflict Avoidance: Separate modules directory prevents JPMS package export conflicts

Testing

The implementation successfully:

  • Builds Maven distribution with new module structure
  • Provides clean separation between JPMS modules and regular dependencies
  • Avoids JPMS module resolution conflicts
  • Maintains compatibility with existing Maven functionality

Scope

This PR focuses solely on JLine JPMS support and does not include broader classworlds module changes. It provides a clean, isolated improvement that can be merged independently.


Related to: Issue apache#11028 - JPMS module support for --enable-native-access

gnodet added 2 commits August 9, 2025 13:27
This implementation provides clean JPMS module support for JLine native
access without modifying maven-classworlds. The changes include:

1. Updated launcher scripts (mvn, mvn.cmd) to use:
   - --module-path pointing to modules/ directory
   - --add-modules org.jline.nativ to ensure proper module loading
   - --enable-native-access=org.jline.nativ for targeted permissions

2. Created modules/ directory in distribution assembly:
   - Includes JLine JARs that need module path access
   - Separates them from regular lib/ dependencies

3. Updated apache-maven POM:
   - Replaced jline-terminal-ffm with jline-native dependency
   - Maintains existing native library extraction

4. Updated classworlds configuration:
   - Added modules/*.jar to load path for compatibility

Benefits:
- Moves away from --enable-native-access=ALL-UNNAMED
- Uses specific module-based native access permissions
- Provides clean JPMS foundation for JLine components
- Maintains dual classpath/module path for compatibility

Note: This branch is based on master and focuses solely on JLine JPMS
changes without the broader classworlds module modifications.
Key insight from testing: Cannot use lib/ directory as module path because
multiple Maven JARs export the same packages, causing JPMS resolution conflicts.

Example conflict:
- maven-core and maven-artifact both export org.apache.maven.artifact.resolver.filter
- This violates JPMS requirement that only one module can export a package

Solution: Separate modules/ directory containing only JLine JARs avoids conflicts
while providing clean JPMS module resolution for native access control.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant