Skip to content

Conversation

gnodet
Copy link
Member

@gnodet gnodet commented Aug 5, 2025

Complete JPMS Migration with Java 24 Support

This PR implements comprehensive Java Platform Module System (JPMS) support for JLine 4.0, enabling modular applications while maintaining full backward compatibility.

🎯 Key Achievements

✅ JPMS Modules (12 modules)

  • Core Infrastructure: terminal, reader, style, native
  • Terminal Providers: terminal-jni (recommended), terminal-ffm (Java 22+), terminal-jna
  • Extended Functionality: builtins, console, console-ui, jansi-core
  • UI Components: curses (newly converted from automatic module)

❌ Automatic Modules (6 modules)

  • terminal-jansi (deprecated - use JNI instead), groovy, remote-ssh, remote-telnet, demo, graal
  • Remain automatic for compatibility with complex external dependencies

🚀 Java 24 Support

  • FFM Provider: Foreign Function Memory API integration for best performance
  • Native Access: Requires --enable-native-access=org.jline.terminal.ffm on module path
  • Future-Ready: Prepared for modern JDK features

🔧 Technical Implementation

Strong Module Boundaries

module org.jline.terminal {
    requires java.base;
    requires java.logging;
    
    exports org.jline.terminal;
    exports org.jline.terminal.spi;
    
    uses org.jline.terminal.spi.TerminalProvider;
}

Service Provider Interface

  • Automatic Discovery: Terminal providers discovered via SPI
  • Priority Selection: JNI → FFM → JNA → Jansi (deprecated)
  • Pluggable Architecture: Easy to add new terminal implementations

Recommended Provider Priority

  1. 🥇 JNI (org.jline.terminal.jni) - No external dependencies, JDK 11+
  2. 🥈 FFM (org.jline.terminal.ffm) - Best performance, JDK 22+
  3. 🥉 JNA (org.jline.terminal.jna) - Alternative with JNA dependency
  4. ❌ Jansi (org.jline.terminal.jansi) - Deprecated, use JNI instead

📋 Migration Guide

For New Modular Applications

module your.app {
    requires org.jline.terminal;
    requires org.jline.reader;
    requires org.jline.terminal.jni; // Recommended provider
    
    // Optional functionality
    requires org.jline.builtins;     // Built-in commands
    requires org.jline.curses;       // UI components
}

For Existing Applications

  • Phase 1: Continue using jline uber-jar (automatic module)
  • Phase 2: Switch to individual modules on classpath
  • Phase 3: Convert application to JPMS module
  • Phase 4: Optimize by removing unused modules

FFM Provider Setup (JDK 22+)

# ✅ CORRECT: JLine on module path
java --module-path jline-modules/ \
     --enable-native-access=org.jline.terminal.ffm \
     --module your.app/your.Main

# ❌ INCORRECT: JLine on classpath (flag won't work)
java -cp jline-jars:your-app.jar \
     --enable-native-access=org.jline.terminal.ffm \
     your.Main

🧪 Testing & Validation

  • ✅ 1,300+ tests passing across all modules
  • ✅ Full build success with mvn install
  • ✅ Java 22+ compatibility verified
  • ✅ Backward compatibility maintained
  • ✅ Service provider discovery working correctly

📚 Documentation

New JPMS Guide

  • Complete migration instructions from JLine 3.x
  • Provider selection recommendations with rationale
  • Module path requirements for FFM native access
  • Troubleshooting section for common JPMS issues
  • Best practices for different application types

Key Documentation Sections

  • Module overview with JDK requirements
  • Provider priority and selection guide
  • Migration strategies for existing applications
  • Troubleshooting common module path issues

🔄 Backward Compatibility

  • ✅ Classpath applications continue to work unchanged
  • ✅ Uber-bundles (jline, jansi) remain as automatic modules
  • ✅ No breaking API changes in public interfaces
  • ✅ Existing build configurations work without modification

🎁 Benefits

  • 🔒 Strong Encapsulation: Internal APIs properly hidden from consumers
  • ⚡ Better Performance: Module system enables JVM optimizations
  • 🛡️ Enhanced Security: Reduced attack surface through encapsulation
  • 🔍 Compile-time Safety: Explicit dependencies prevent runtime issues
  • 🚀 Future-Ready: Foundation for modern Java features

🏗️ Architecture

graph TD
    A[Application] --> B[org.jline.reader]
    B --> C[org.jline.terminal]
    C --> D[Terminal Providers]
    D --> E[org.jline.terminal.jni]
    D --> F[org.jline.terminal.ffm]
    D --> G[org.jline.terminal.jna]
    B --> H[org.jline.builtins]
    A --> I[org.jline.curses]
Loading

This migration establishes JLine as a modern, modular Java library ready for the next decade of Java development while ensuring existing applications continue to work seamlessly.

@gnodet gnodet marked this pull request as draft August 5, 2025 20:07
@gnodet gnodet added the feature label Aug 5, 2025
@gnodet gnodet added this to the 4.0.0 milestone Aug 6, 2025
@gnodet gnodet force-pushed the jpms-migration branch 4 times, most recently from dfbe2df to 3baaab1 Compare August 6, 2025 21:15
@gnodet gnodet marked this pull request as ready for review August 6, 2025 21:27
@gnodet gnodet force-pushed the jpms-migration branch 6 times, most recently from 7782a93 to da99f27 Compare August 7, 2025 10:15
This PR implements comprehensive Java Platform Module System (JPMS) support
for JLine 4.0, enabling modular applications while maintaining full backward
compatibility.

## Key Changes

JPMS Modules (12 modules):
- Core: terminal, reader, style, native
- Providers: terminal-jni (recommended), terminal-ffm (JDK 22+), terminal-jna
- Extended: builtins, console, console-ui, jansi-core, curses

Automatic Modules (6 modules):
- terminal-jansi (deprecated), groovy, remote-ssh, remote-telnet, demo, graal
- Remain automatic for compatibility with complex dependencies

Java 24 Support:
- FFM (Foreign Function Memory) API integration
- Requires --enable-native-access=org.jline.terminal.ffm on module path
- Best performance terminal provider for modern JDK

## Technical Implementation

Strong Encapsulation:
- Proper module-info.java with explicit exports/requires
- Internal APIs hidden from consumers
- Service Provider Interface (SPI) for terminal providers

Provider Recommendations:
1. JNI (recommended): No external dependencies, no special permissions, JDK 11+
2. FFM (best performance): Requires --enable-native-access, JDK 22+
3. JNA (alternative): Requires JNA dependency
4. Jansi (deprecated): Use JNI instead

Key Technical Details:
- JNI provider uses traditional JNI (no native access permissions needed)
- FFM provider uses Panama FFM API (requires --enable-native-access)
- Module path required for FFM native access to work
- Service provider discovery for automatic terminal provider selection

Backward Compatibility:
- Classpath applications work unchanged
- Uber-bundles (jline, jansi) remain as automatic modules
- No breaking API changes

## Documentation

Complete JPMS guide with migration instructions, provider selection
recommendations, module path requirements for FFM native access,
JNI vs FFM comparison and setup instructions, troubleshooting guide
for common JPMS issues, and best practices for different application types.

This migration provides the foundation for JLine's future development
while ensuring existing applications continue to work seamlessly.
@gnodet gnodet merged commit 8b39f3d into master Aug 7, 2025
9 checks passed
gnodet added a commit to gnodet/jline3 that referenced this pull request Aug 7, 2025
This PR implements comprehensive Java Platform Module System (JPMS) support
for JLine 4.0, enabling modular applications while maintaining full backward
compatibility.

## Key Changes

JPMS Modules (12 modules):
- Core: terminal, reader, style, native
- Providers: terminal-jni (recommended), terminal-ffm (JDK 22+), terminal-jna
- Extended: builtins, console, console-ui, jansi-core, curses

Automatic Modules (6 modules):
- terminal-jansi (deprecated), groovy, remote-ssh, remote-telnet, demo, graal
- Remain automatic for compatibility with complex dependencies

Java 24 Support:
- FFM (Foreign Function Memory) API integration
- Requires --enable-native-access=org.jline.terminal.ffm on module path
- Best performance terminal provider for modern JDK

## Technical Implementation

Strong Encapsulation:
- Proper module-info.java with explicit exports/requires
- Internal APIs hidden from consumers
- Service Provider Interface (SPI) for terminal providers

Provider Recommendations:
1. JNI (recommended): No external dependencies, no special permissions, JDK 11+
2. FFM (best performance): Requires --enable-native-access, JDK 22+
3. JNA (alternative): Requires JNA dependency
4. Jansi (deprecated): Use JNI instead

Key Technical Details:
- JNI provider uses traditional JNI (no native access permissions needed)
- FFM provider uses Panama FFM API (requires --enable-native-access)
- Module path required for FFM native access to work
- Service provider discovery for automatic terminal provider selection

Backward Compatibility:
- Classpath applications work unchanged
- Uber-bundles (jline, jansi) remain as automatic modules
- No breaking API changes

## Documentation

Complete JPMS guide with migration instructions, provider selection
recommendations, module path requirements for FFM native access,
JNI vs FFM comparison and setup instructions, troubleshooting guide
for common JPMS issues, and best practices for different application types.

This migration provides the foundation for JLine's future development
while ensuring existing applications continue to work seamlessly.
@gnodet gnodet deleted the jpms-migration branch August 7, 2025 14:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants