Closed jvalkeal closed 10 months ago
So it looks to be CLibrary.openpty()
in LinuxNativePty.open()
which throws that hard error if org.jline:jline-terminal-jna
is in a classpath. If jna
is not in a classpath then newTerminal
throws NoClassDefFoundError
and JLine catches that and moves on.
Not sure to understand, is the problem with the JNI provider or the JNA provider ? Or are those two different problems ?
I'm a bit rusty with this jni stuff so give me some rope here. Looks like when this /tmp/jlinenative-3.24.1-e342cc4f6f2aa9de-libjlinenative.so
is extracted and used this call
doesn't work. Looking ldd:
$ ldd /tmp/jlinenative-3.24.1-e342cc4f6f2aa9de-libjlinenative.so
linux-vdso.so.1 (0x00007fff87b3c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc9d0365000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc9d0959000)
I don't see it linking to libutil
where I think openpty
is. If I do:
export LD_PRELOAD=/lib/x86_64-linux-gnu/libutil.so.1
before build then the error goes away.
Quickest way to see this in JLine itself is to force system
to false
and run demo. Felix sets system
to true
so I had to tweak a code.
$ git diff
diff --git a/terminal/src/main/java/org/jline/terminal/TerminalBuilder.java b/terminal/src/main/java/org/jline/terminal/TerminalBuilder.java
index 64708c7d..a08d5ea0 100644
--- a/terminal/src/main/java/org/jline/terminal/TerminalBuilder.java
+++ b/terminal/src/main/java/org/jline/terminal/TerminalBuilder.java
@@ -148,7 +148,7 @@ public final class TerminalBuilder {
private String type;
private Charset encoding;
private int codepage;
- private Boolean system;
+ private Boolean system = false;
private SystemOutput systemOutput;
private String provider;
private String providers;
@@ -179,7 +179,7 @@ public final class TerminalBuilder {
}
public TerminalBuilder system(boolean system) {
- this.system = system;
+ // this.system = system;
return this;
}
13:07 $ ./build demo
Launching Gogo JLine...
Classpath: /home/jvalkealahti/repos/jvalkeal/jline3/demo/target/classes:/home/jvalkealahti/repos/jvalkeal/jline3/demo/target/lib/jline-terminal-jni-3.24.2-SNAPSHOT.jar:/home/jvalkealahti/repos/jvalkeal/jline3/demo/target/lib/jline-terminal-jansi-3.24.2-SNAPSHOT.jar:/home/jvalkealahti/repos/jvalkeal/jline3/demo/target/lib/jline-console-3.24.2-SNAPSHOT.jar:/home/jvalkealahti/repos/jvalkeal/jline3/demo/target/lib/jline-remote-telnet-3.24.2-SNAPSHOT.jar:/home/jvalkealahti/repos/jvalkeal/jline3/demo/target/lib/jline-terminal-3.24.2-SNAPSHOT.jar:/home/jvalkealahti/repos/jvalkeal/jline3/demo/target/lib/jline-builtins-3.24.2-SNAPSHOT.jar:/home/jvalkealahti/repos/jvalkeal/jline3/demo/target/lib/jline-style-3.24.2-SNAPSHOT.jar:/home/jvalkealahti/repos/jvalkeal/jline3/demo/target/lib/jline-remote-ssh-3.24.2-SNAPSHOT.jar:/home/jvalkealahti/repos/jvalkeal/jline3/demo/target/lib/jline-terminal-jna-3.24.2-SNAPSHOT.jar:/home/jvalkealahti/repos/jvalkeal/jline3/demo/target/lib/jline-terminal-ffm-3.24.2-SNAPSHOT.jar:/home/jvalkealahti/repos/jvalkeal/jline3/demo/target/lib/jline-reader-3.24.2-SNAPSHOT.jar:/home/jvalkealahti/repos/jvalkeal/jline3/demo/target/lib/jline-native-3.24.2-SNAPSHOT.jar:/home/jvalkealahti/repos/jvalkeal/jline3/demo/target/lib/jline-groovy-3.24.2-SNAPSHOT.jar:/home/jvalkealahti/repos/jvalkeal/jline3/demo/target/lib/org.apache.felix.gogo.runtime-1.1.6.jar:/home/jvalkealahti/repos/jvalkeal/jline3/demo/target/lib/org.apache.felix.gogo.jline-1.1.8.jar
java: symbol lookup error: /tmp/jlinenative-3.24.2-349cf11782093e50-libjlinenative.so: undefined symbol: openpty
In my issue above I used custom streams(for doing testing), so it ended up calling:
Sorry for the delay. The thing I'm wondering about, is how to change the makefile so that the libraries are linked with libutil
...
You may need to load required libraries explicitly whenever you use Linker.nativeLinker() . Linker.defaultLookup() behaves differently depending on architecture, I dont think it is reliable.
I'm still debugging this issue on my side but I wanted to throw this out here if it immediately rings a bell.
When trying to use
3.24.1
I'm getting into trouble with tests(where I don't have a proper tty). I getjni
andexec
and thenjni
fails withnewTerminal
withIf I run my cli in a real terminal and attach debugger, I have
jni
,jansi
,jna
andexec
butjni
doesn't fail withsysTerminal
and I getPosixSysTerminal
.I'm on
Ubuntu 18.04.6 LTS
in this system.