mordant icon indicating copy to clipboard operation
mordant copied to clipboard

Creating a Terminal fails running with a TTY on Java 21

Open Mahoney opened this issue 4 months ago • 3 comments

We're seeing exceptions at runtime initialising a Terminal in interactive mode, but only for JRE 20 and 21:

java.lang.ClassCastException: Cannot cast java.lang.Integer to java.lang.foreign.MemorySegment
	at java.base/java.lang.Class.cast(Class.java:4067)
	at java.base/java.lang.invoke.VarHandles.insertCoordinates(VarHandles.java:501)
	at java.base/java.lang.invoke.MethodHandles.insertCoordinates(MethodHandles.java:8144)
	at com.github.ajalt.mordant.terminal.terminalinterface.ffm.FfmLayoutsKt.varHandle(FfmLayouts.kt:133)
	at com.github.ajalt.mordant.terminal.terminalinterface.ffm.FfmLayoutsKt$shortField$$inlined$scalarField$default$1$1.invoke(FfmLayouts.kt:84)
	at com.github.ajalt.mordant.terminal.terminalinterface.ffm.FfmLayoutsKt$shortField$$inlined$scalarField$default$1$1.invoke(FfmLayouts.kt:81)
	at com.github.ajalt.mordant.terminal.terminalinterface.ffm.StructAccessor$DefaultImpls.getValue(FfmLayouts.kt:117)
	at com.github.ajalt.mordant.terminal.terminalinterface.ffm.MacosCLibrary$winsize.getValue(TerminalInterface.ffm.macos.kt:11)
	at com.github.ajalt.mordant.terminal.terminalinterface.ffm.MacosCLibrary$winsize.getWs_col(TerminalInterface.ffm.macos.kt:22)
	at com.github.ajalt.mordant.terminal.terminalinterface.ffm.TerminalInterfaceFfmMacos.getTerminalSize(TerminalInterface.ffm.macos.kt:89)
	at com.github.ajalt.mordant.terminal.TerminalDetectionKt.detectSize(TerminalDetection.kt:217)
	at com.github.ajalt.mordant.terminal.Terminal.<init>(Terminal.kt:81)

All works fine on Java 17-19, and on Java 22-25.

Tested on macOs and Ubuntu using Temurin JREs.

Mahoney avatar Oct 29 '25 16:10 Mahoney

I'm trying to put together something in the GitHub Actions so that a build job emits the jar file(s) and a subsequent matrix build can run the detection sample against 17, 21 & 25 JREs (i.e. all the LTEs), if that would be valuable?

Mahoney avatar Oct 29 '25 16:10 Mahoney

Yes, I'd appreciate that.

The error itself is odd; the ffm module that's causing that exception is only supported on JDK 22+, it should even be loaded on 21. Maybe we need to explicitly check for JDK 21 rather than rely on the NoClassDef error

ajalt avatar Oct 29 '25 22:10 ajalt

I've found some more specific info.

We are running java --enable-native-access=ALL-UNNAMED in order to avoid getting this message on Java 24 & 25:

WARNING: A restricted method in java.lang.System has been called WARNING: java.lang.System::load has been called by v.I in an unnamed module (file:/Users/robert/dev/thirdparty/mordant/test/proguard/build/libs/main-r8.jar) WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module WARNING: Restricted methods will be blocked in a future release unless native access is enabled

However, on Java 20 & 21 this causes Terminal.<init>(Terminal.kt:81) to throw the exception.

If we omit this option Mordant works OK against all Java versions 17-25.

(Odd that it works OK with that option on Java 17, 18, & 19; perhaps that option does nothing on those.)

Not sure if that means this is something that needs fixing or not?

Mahoney avatar Nov 15 '25 13:11 Mahoney