Problem
All aesh-readline modules are unnamed modules. They use META-INF/services for ServiceLoader discovery and have no module-info.java. This means:
- They cannot be used as named modules in modular applications
- They appear as automatic modules on the module path (module name derived from
Automatic-Module-Name manifest entry)
- The FFM terminal provider requires
--enable-native-access=ALL-UNNAMED (because the module is unnamed)
Status: Deferred
Blocked on Java 8 → 11 baseline migration. Both aesh-readline and aesh currently use maven.compiler.release=8. module-info.java requires Java 9+. The baseline bump should be coordinated across both projects (aesh-readline first, then aesh).
Analysis
Split package blocker
org.aesh.terminal.tty is a split package — classes exist in both terminal-api and terminal-tty:
terminal-api (10 API types — stay in place):
Capability, MouseEvent, MouseTracking, Point, ScreenRegion, Signal, Size, SplitScreen, StatusLine, TtyOutputMode
terminal-tty (7 implementation classes — must move):
TerminalConnection, TerminalBuilder, TerminalDevice, TerminalColorDetector, PlatformThemeDetector, DeviceBuilder, TtyDetect
JPMS forbids two named modules from containing the same package. This must be resolved before adding module-info.java.
Proposed rename: org.aesh.terminal.tty.{class} → org.aesh.terminal.tty.conn.{class} for the 7 terminal-tty classes.
Impact of the rename (import counts across aesh-readline + aesh):
| Class |
External imports |
Notes |
TerminalConnection |
21 |
Most disruptive — used in readline, examples, aesh |
DeviceBuilder |
4 |
Used by readline EditModeBuilder |
TtyDetect |
2 |
Used by aesh LazyTerminalShell |
TerminalColorDetector |
1 |
One example |
TerminalBuilder |
0 |
Internal to terminal-tty |
TerminalDevice |
0 |
Internal to terminal-tty |
PlatformThemeDetector |
0 |
Internal to terminal-tty |
External dependency JPMS readiness
All external compile-scope dependencies have JPMS support:
| Dependency |
JPMS mechanism |
Module name |
| Netty 4.2.x |
MRJAR module-info (Java 11+) |
io.netty.common, .transport, .handler, .codec.http |
| commons-logging 1.4.0 |
MRJAR module-info (Java 9+) |
org.apache.commons.logging |
| sshd-core 2.19.0 |
Automatic-Module-Name |
org.apache.sshd.core |
| sshd-netty 2.19.0 |
Automatic-Module-Name |
org.apache.sshd.netty |
| jackson-databind 2.22.2 |
MRJAR module-info (Java 9+) |
com.fasterxml.jackson.databind |
No blockers from external dependencies.
Existing Automatic-Module-Name values
All modules already declare Automatic-Module-Name in MANIFEST.MF — these become the JPMS module names:
| Module |
Automatic-Module-Name |
| terminal-detect |
org.aesh.terminal.detect |
| terminal-api |
org.aesh.terminal.api |
| readline-api |
org.aesh.readline.api |
| terminal-tty |
org.aesh.terminal.tty |
| readline |
org.aesh.readline |
| terminal-ssh |
org.aesh.terminal.ssh |
| terminal-telnet |
org.aesh.terminal.telnet |
| terminal-http |
org.aesh.terminal.http |
Implementation plan
Phase 0: Raise baseline to Java 11
- Change
maven.compiler.release from 8 to 11 in parent pom.xml
- Coordinate with aesh: bump aesh-readline dependency, then bump aesh to Java 11
Phase 1: Fix split package
- Move terminal-tty's 7 classes from
org.aesh.terminal.tty to org.aesh.terminal.tty.conn
- Update all imports in terminal-tty sub-packages (
impl/, provider/, split/)
- Update imports in
readline, examples, aesh project, README, project site docs
- Consider deprecated forwarding classes in old package for one release cycle
Phase 2: Add module-info.java (bottom-up)
terminal-detect:
module org.aesh.terminal.detect {
exports org.aesh.terminal.detect;
}
terminal-api:
module org.aesh.terminal.api {
requires transitive org.aesh.terminal.detect;
exports org.aesh.terminal;
exports org.aesh.terminal.formatting;
exports org.aesh.terminal.image;
exports org.aesh.terminal.io;
exports org.aesh.terminal.parser;
exports org.aesh.terminal.provider;
exports org.aesh.terminal.tty;
exports org.aesh.terminal.utils;
}
readline-api:
module org.aesh.readline.api {
requires transitive org.aesh.terminal.api;
exports org.aesh.readline.completion;
exports org.aesh.readline.prompt;
exports org.aesh.readline.suggestion;
}
terminal-tty:
module org.aesh.terminal.tty {
requires transitive org.aesh.terminal.api;
exports org.aesh.terminal.tty.conn;
exports org.aesh.terminal.tty.provider;
exports org.aesh.terminal.tty.split;
provides org.aesh.terminal.provider.TerminalProvider with
org.aesh.terminal.tty.provider.FfmTerminalProvider,
org.aesh.terminal.tty.provider.WinSysTerminalProvider,
org.aesh.terminal.tty.provider.CygwinTerminalProvider,
org.aesh.terminal.tty.provider.ExecPtyTerminalProvider;
}
Key benefit: --enable-native-access=org.aesh.terminal.tty replaces ALL-UNNAMED.
MRJAR note: module-info.java goes in src/main/java/ (compiled at release=11). The Java 22 FFM overlay does not need its own module descriptor.
readline:
module org.aesh.readline {
requires transitive org.aesh.terminal.api;
requires transitive org.aesh.readline.api;
requires org.aesh.terminal.tty;
exports org.aesh.readline;
exports org.aesh.readline.action;
exports org.aesh.readline.action.mappings;
exports org.aesh.readline.alias;
exports org.aesh.readline.editing;
exports org.aesh.readline.fuzzy;
exports org.aesh.readline.history;
// internal: cursor, paste, undo, util, completion.impl
}
terminal-ssh:
module org.aesh.terminal.ssh {
requires transitive org.aesh.terminal.api;
requires io.netty.common;
requires io.netty.transport;
requires io.netty.handler;
requires static org.apache.sshd.core;
requires static org.apache.sshd.netty;
exports org.aesh.terminal.ssh;
exports org.aesh.terminal.ssh.netty;
}
terminal-telnet:
module org.aesh.terminal.telnet {
requires transitive org.aesh.terminal.api;
requires io.netty.common;
requires io.netty.transport;
requires io.netty.handler;
exports org.aesh.terminal.telnet;
exports org.aesh.terminal.telnet.netty;
}
terminal-http:
module org.aesh.terminal.http {
requires transitive org.aesh.terminal.api;
requires io.netty.common;
requires io.netty.transport;
requires io.netty.handler;
requires io.netty.codec.http;
requires com.fasterxml.jackson.databind;
exports org.aesh.terminal.http;
exports org.aesh.terminal.http.netty;
}
Phase 3: Build configuration
- Remove
Automatic-Module-Name from maven-jar-plugin manifest entries (redundant with module-info.java)
- Keep
META-INF/services files alongside provides clauses (classpath users need them)
- Change
Enable-Native-Access manifest entry from ALL-UNNAMED to org.aesh.terminal.tty
Phase 4: Testing
- Verify no split package errors on module path
- Run full test suite (Surefire runs on classpath — should pass without changes)
- Test explicit module path usage with a small test app
- Test
--enable-native-access=org.aesh.terminal.tty
- Test GraalVM native image
- Test classpath-only backward compatibility
Estimated effort
~6-8 hours total, best done as a coordinated effort across aesh-readline and aesh after the Java 11 baseline migration.
Problem
All aesh-readline modules are unnamed modules. They use
META-INF/servicesfor ServiceLoader discovery and have nomodule-info.java. This means:Automatic-Module-Namemanifest entry)--enable-native-access=ALL-UNNAMED(because the module is unnamed)Status: Deferred
Blocked on Java 8 → 11 baseline migration. Both aesh-readline and aesh currently use
maven.compiler.release=8.module-info.javarequires Java 9+. The baseline bump should be coordinated across both projects (aesh-readline first, then aesh).Analysis
Split package blocker
org.aesh.terminal.ttyis a split package — classes exist in bothterminal-apiandterminal-tty:terminal-api (10 API types — stay in place):
Capability,MouseEvent,MouseTracking,Point,ScreenRegion,Signal,Size,SplitScreen,StatusLine,TtyOutputModeterminal-tty (7 implementation classes — must move):
TerminalConnection,TerminalBuilder,TerminalDevice,TerminalColorDetector,PlatformThemeDetector,DeviceBuilder,TtyDetectJPMS forbids two named modules from containing the same package. This must be resolved before adding
module-info.java.Proposed rename:
org.aesh.terminal.tty.{class}→org.aesh.terminal.tty.conn.{class}for the 7 terminal-tty classes.Impact of the rename (import counts across aesh-readline + aesh):
TerminalConnectionDeviceBuilderEditModeBuilderTtyDetectLazyTerminalShellTerminalColorDetectorTerminalBuilderTerminalDevicePlatformThemeDetectorExternal dependency JPMS readiness
All external compile-scope dependencies have JPMS support:
io.netty.common,.transport,.handler,.codec.httporg.apache.commons.loggingorg.apache.sshd.coreorg.apache.sshd.nettycom.fasterxml.jackson.databindNo blockers from external dependencies.
Existing Automatic-Module-Name values
All modules already declare
Automatic-Module-Namein MANIFEST.MF — these become the JPMS module names:org.aesh.terminal.detectorg.aesh.terminal.apiorg.aesh.readline.apiorg.aesh.terminal.ttyorg.aesh.readlineorg.aesh.terminal.sshorg.aesh.terminal.telnetorg.aesh.terminal.httpImplementation plan
Phase 0: Raise baseline to Java 11
maven.compiler.releasefrom8to11in parent pom.xmlPhase 1: Fix split package
org.aesh.terminal.ttytoorg.aesh.terminal.tty.connimpl/,provider/,split/)readline,examples, aesh project, README, project site docsPhase 2: Add module-info.java (bottom-up)
terminal-detect:
terminal-api:
readline-api:
terminal-tty:
Key benefit:
--enable-native-access=org.aesh.terminal.ttyreplacesALL-UNNAMED.MRJAR note:
module-info.javagoes insrc/main/java/(compiled at release=11). The Java 22 FFM overlay does not need its own module descriptor.readline:
terminal-ssh:
terminal-telnet:
terminal-http:
Phase 3: Build configuration
Automatic-Module-Namefrommaven-jar-pluginmanifest entries (redundant withmodule-info.java)META-INF/servicesfiles alongsideprovidesclauses (classpath users need them)Enable-Native-Accessmanifest entry fromALL-UNNAMEDtoorg.aesh.terminal.ttyPhase 4: Testing
--enable-native-access=org.aesh.terminal.ttyEstimated effort
~6-8 hours total, best done as a coordinated effort across aesh-readline and aesh after the Java 11 baseline migration.