Fork me on GitHub
#lsp
<
2023-11-05
>
Tomas Brejla17:11:19

I'm trying to use graalvm native build (aarch) on termux (android). It's failing when trying to access /tmp dir at this line https://github.com/clojure-lsp/clojure-lsp/blob/master/cli/src/clojure_lsp/server.clj#L72. The non-native version works fine. I'd expect both non-native and native versions should respect $TMPDIR env property on runtime. Is it possible that the /tmp value got somehow pre-baked in on graalvm native-compile time?

borkdude18:11:40

Counter-evidence:

$ TMPDIR=foo bb -e '(System/getenv "TMPDIR")'
"foo"

borkdude18:11:58

Ah you mean when you through ?

$ TMPDIR=foo bb -e '(java.io.File/createTempFile "clojure-lsp." ".out")'
#object[java.io.File 0xae2c0bd "/var/folders/j9/xmjlcym958b1fr0npsp9msvh0000gn/T/clojure-lsp.2007191518125411009.out"]

borkdude18:11:31

This also doesn't help:

bb -Djava.io.tmpdir=foo -e '(java.io.File/createTempFile "clojure-lsp." ".out")'
#object[java.io.File 0x1bd80170 "/var/folders/j9/xmjlcym958b1fr0npsp9msvh0000gn/T/clojure-lsp.11281604918901136101.out"]
Perhaps this happens because java.io.File is initialized at build time

Tomas Brejla18:11:07

Yes,bthat would be my expectation.. it would explain the the different behavior between uberjar and native

borkdude19:11:03

but wait, I don't explicitly initialize java.io.File at build time, so I think it's a graalvm bug actually:

borkdude19:11:40

clojure-lsp could fix this by passing an explicit tmp dir based on the dynamic system property

Tomas Brejla20:11:27

As always, thanks for looking into this! 👍 🙏 Regarding possible hotfix om clojure-lsp.. Well, not having /tmp (or similar in other OSs) accessible (and writable) is probably a very niche situation.. so this bug probably doesn't affect too many users. Therefore it may not be worth it to make a workaround of this issue in clojure-lsp - and we can just wait and see if that bug gets accepted and fixed in graalvm. On the other hand, it's a pitty that a failure in initializion of logging subsystem results in native binary being unusable. (not sure if createTempFile is used on other places). Perhaps this specific logging initialization deserves to be be made a bit more robust? It's still great news that there's an alternative workaround: go simply use the non-native standalone version (uberjar with leading script). Works fine, it just takes a while to start it.

ericdallo22:11:21

Thanks for the help @U04V15CAJ! @U01LFP3LA6P completely agree, that java method is called only there indeed, we could change to try catch and create in another dir, but what dir? I think we can check if using the uberjar is enough to you, I do think it's a corner case only few users may face

borkdude22:11:04

but what dirwell, exactly the directory that java.io.tmpdir is pointed at at runtime?

ericdallo22:11:42

Hum, and how to get that?

borkdude22:11:21

(System/getProperty "java.io.tmpdir")

ericdallo22:11:52

Ah got it, that sounds like a good hotfix, I can do that. Do you think we should change to always use that? otherwise how to know if we should use the property or the method?

borkdude22:11:47

I think it's good to always use that, it is what Java uses internally as well, but native image captures that property at build time in that method I think

borkdude22:11:42

I don't know how easy it is for people to pass that property to clojure-lsp in their tooling though, you need to call it with:

clojure-lsp -Djava.io.tmpdir=...

ericdallo22:11:06

Ah yeah, we could check if the property is present, and use it, but don't know if that would be enough for all users, but since it's a pretty specific case, WDYT @U01LFP3LA6P

borkdude22:11:35

That property is always present, it is set by Java

ericdallo22:11:28

I see, so we could always use the property, and if o e wants to override just need to pass that right

ericdallo22:11:18

@U01LFP3LA6P feel free to create a issue, should be a pretty straightforward fix/improvement

borkdude23:11:30

I think this should fix Tomas's problem without adding the system property manually, since it will read the property at runtime - probably, but needs testing of course

borkdude23:11:48

Maybe @U01LFP3LA6P can run bb -e '(System/getProperty ".tmpdir")' on that problematic system to see if that returns the right directory, if so, the proposed workarounds should solve it

Tomas Brejla23:11:53

I wouldn't be concerned too much regarding how easy it is for people to pass that property to clojure-lsp in their tooling . If I'm affected by this bug and know that - as hopefully a temporary workaround - I have to pass java.io.tmpdir to clojure-lsp, I believe I can always create a surrogate clojure-lsp"bash" script, that I'll place just in front of the the original clojure-lspnative binary - and from which I can pass anything I like to the real native binary.

Tomas Brejla23:11:25

> Maybe @U01LFP3LA6P can run bb -e '(System/getProperty ".tmpdir")' on that problematic system to see if that returns the right directory, if so, the proposed workarounds should solve it (edite bb should be native aarch binary on that device, right?

Tomas Brejla23:11:14

2 weird things. 1. I can't use -ecorrectly. With bb -e '(+ 1 1)' I get EOF while reading, expected ) to match ( at [1,1]. Something seriously weird, but I don't want to be distracted by it now. 2. I can still fire up bb repl using just bb and from there, evaluations behave normally. Then, the (System/getProperty ".tmpdir") returns /tmp. I wonder.. why...

Tomas Brejla23:11:50

in the shell I'm starting bb from, echo $TMPDIR points to /data/data/com.termux/files/usr/tmp, which does exist. /tmp doesnt.

Tomas Brejla23:11:34

hmmm.. from the same shell: jshell with java.lang.System.getProperty(".tmpdir") returns the correct /data/... path

Tomas Brejla23:11:26

There might definitely be something fishy on that termux tablet. But then again you observed the problem with File/createTempFile with native binaries as well, even on Mac, right?

Tomas Brejla23:11:03

Regarding bb -e not working correctly - that only seems to be an issue with (my)zsh on that machine. In regular bash, bb -e works as expected

Tomas Brejla23:11:44

btw (System/getProperties) itself is a weird beast with native binary. things like java.library.path are pointing to non-existing paths as well :thinking_face:

Tomas Brejla23:11:58

~ $ bb -e '(System/getProperties)'

{"java.specification.version" "21", "org.graalvm.nativeimage.kind" "executable", "sun.jnu.encoding" "UTF-8", "java.runtime.version" "21.0.1+12-jvmci-23.1-b19", "java.class.path" "", "user.name" "u0_a306", "stdout.encoding" "UTF-8", "path.separator" ":", "java.vm.vendor" "Oracle Corporation", "sun.arch.data.model" "64", "os.version" "5.4.210-qgki-27114284-abT733XXU5CWI4", "java.endorsed.dirs" "", "java.runtime.name" "GraalVM Runtime Environment", "java.vendor.url" "", "file.encoding" "UTF-8", "java.vm.specification.version" "21", "java.vm.name" "Substrate VM", "os.name" "Linux", "java.vendor.version" "Oracle GraalVM 21.0.1+12.1", "babashka.version" "1.3.186", "jdk.lang.Process.launchMechanism" "FORK", "java.io.tmpdir" "/tmp", "java.version" "21.0.1", "user.dir" "/data/data/com.termux/files/home", "user.home" "/data/data/com.termux/files/home", "os.arch" "aarch64", "java.specification.vendor" "Oracle Corporation", "java.vm.specification.name" "Java Virtual Machine Specification", "org.graalvm.nativeimage.imagecode" "runtime", "java.version.date" "2023-10-17", "file.separator" "/", "native.encoding" "UTF-8", "line.separator" "\n", "java.library.path" "/usr/lib64:/lib64:/lib:/usr/lib", "java.vendor" "Oracle Corporation", "java.vm.specification.vendor" "Oracle Corporation", "java.specification.name" "Java Platform API Specification", "stderr.encoding" "UTF-8", "" "serial gc, compressed references", "java.vm.version" "21.0.1+12", "java.ext.dirs" "", "java.class.version" "65.0"}

Tomas Brejla23:11:25

btw looking back.. before I actually studied the stacktrace to find the root cause, I was hoping that I can put :log-path to my ~/.config/clojure-lsp/config.edn and everything will be fine. But it seems (at least strace suggested so) that the config file doesn't get read at all before that problematic File/createTempFilecall. Perhaps a workaround could lie somewhere in these waters. Are you hit by that issue? Make sure that you use :log-path in your config and we'll make sure to pick it from there :thinking_face:

Tomas Brejla23:11:57

(I hope I'm not mixing apples and oranges here)