Fork me on GitHub
#tools-deps
<
2024-01-04
>
Rachel Westmacott15:01:53

I have two commands and two questions. JDK_JAVA_OPTIONS=-Dclojure.server.repl="'{:address,\"0.0.0.0\",:port,5555,:accept,clojure.core.server/repl,:server-daemon,false,:client-daemon,false}'" clj -M -e '(println "hi")' and JDK_JAVA_OPTIONS=-Dclojure.server.repl="'{:address,\"0.0.0.0\",:port,5555,:accept,clojure.core.server/repl,:server-daemon,false,:client-daemon,false}'" clj -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.12.0-alpha1"}}}' -M -e '(println "hi")' My questions are: "Why does the command that specifies a Clojure version not print 'hi'?" and "Why does the one that specifies Clojure 12 start a Clojure 11 socket repl?" If anyone is able to enlighten me in any regard I should be most grateful.

Rachel Westmacott15:01:54

(apologies if this is the wrong channel - it's hard to know where exactly the issue lies as I don't yet understand it)

Alex Miller (Clojure team)15:01:34

The Clojure CLI potentially runs 2 jvms - the first (optional) one will be run to calculate the classpath based on your deps.edn config. The results of that are cached (in .cpcache), so this will not always happen. The CLI then runs your actual program in the second jvm. The JDK_JAVA_OPTIONS environment variable is applied to ALL jvms, so you are actually running the socket repl from the first classpath-computing jvm - that one is an uberjar that bundles its own version of Clojure (1.11.1).

gratitude 1
Alex Miller (Clojure team)15:01:38

if you want to supply the env vars ONLY to the latter (user) jvm, there is an https://clojure.org/reference/deps_and_cli#env_vars for that: JAVA_OPTS (and if you only want to supply to the classpath-computing jvm, there is an env var for that: CLJ_JVM_OPTS )

gratitude 1
Alex Miller (Clojure team)15:01:26

you can also use -J to pass env vars on the clj command line without using any env vars

gratitude 1
Rachel Westmacott15:01:50

Thank you very much. This is all very helpful.

Rachel Westmacott15:01:57

(and interesting)

Alex Miller (Clojure team)15:01:20

oh, that's actually yet another way to do it :)

Alex Miller (Clojure team)15:01:28

but with -J you would do something like:

clj '-J-Dclojure.server.repl={:address,"0.0.0.0",:port,5555,:accept,clojure.core.server/repl,:server-daemon,false,:client-daemon,false}' -M -e '(println "hi")'

👍 1
Rachel Westmacott15:01:03

I notice that the quoting rules seem to be different for JAVA_OPTS compared to JDK_JAVA_OPTIONS - I assume that's because there's an extra hop in the chain as it gets passed through to the user process.

Rachel Westmacott15:01:16

Thank you! I now have Clojure 12 running in my server repl.

🎉 1
Alex Miller (Clojure team)16:01:21

I would expect the quoting to be the same for the two env vars (but different for -J)

Rachel Westmacott16:01:17

hmm, empirically it didn't seem to be. I swapped out the one for the other in my command and it didn't behave as I had previously expected

Rachel Westmacott16:01:14

this does something JDK_JAVA_OPTIONS=-Dclojure.server.repl="'{:address,\"0.0.0.0\",:port,5555,:accept,clojure.core.server/repl,:server-daemon,false,:client-daemon,false}'" clj -M -e '(println "hi")' whereas this JAVA_OPTS=-Dclojure.server.repl="'{:address,\"0.0.0.0\",:port,5555,:accept,clojure.core.server/repl,:server-daemon,false,:client-daemon,false}'" clj -M -e '(println "hi")' throws an exception ("java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol")

Rachel Westmacott16:01:39

I think the only change I have there is the env var name.

Alex Miller (Clojure team)16:01:50

I don't think that quoting is correct in either case, but not sure why they would differ in behavior. the single quote inside the double quote does not seem right to me - seems like that should make it through to the system property edn reading and act as map quoting (in which case the trailing single quote is probably ignored). And I'm not sure the \" is correct in shell?

Rachel Westmacott16:01:57

I'm absolutely delighted to be schooled in this - I only have what I have through trial and error - I do not know what I am doing when it comes to shells and escaping.

Alex Miller (Clojure team)16:01:21

I guess the former is handled by the jdk directly and the latter is passed on by the clj script so they are different

Alex Miller (Clojure team)16:01:52

in fact, I think the clojure script may be missing double quotes where that happens

Rachel Westmacott16:01:32

I had quite a bit of trouble getting it to retain any double quotes around the :address, so it kept trying to parse it as a number (and failing). What I ended up with was the first thing I found that worked.

Alex Miller (Clojure team)17:01:29

I think you need the \" but should remove the inner ' '

Rachel Westmacott17:01:25

For JAVA_OPTS that's what I've ended up with. When using JDK_JAVA_OPTIONS (which I no longer need) it seems I needed the extra quotes.

Alex Miller (Clojure team)17:01:01

that's not something the shell would use and the clojure code reading that property could at best treat that as a quoted data structure, which is not needed

Rachel Westmacott17:01:57

JDK_JAVA_OPTIONS=-Dclojure.server.repl="{:address,\"0.0.0.0\",:port,5555,:accept,clojure.core.server/repl,:server-daemon,false,:client-daemon,false}" clj -M -e '(println "hi")' gives me a stacktrace ("Invalid number: 0.0.0.0")- perhaps I've misunderstood something

Alex Miller (Clojure team)17:01:35

that works for me

⁉️ 1
Alex Miller (Clojure team)17:01:11

(separately, the clj script is missing quotes for passing $JAVA_OPTS, but that's irrelevant in these particular examples)

Alex Miller (Clojure team)17:01:58

at this point it may become relevant what you have for java -version and clj --version

Rachel Westmacott17:01:01

/bin/bash on Ubuntu | openjdk 17.0.9 | Clojure 1.11.1.1165 if you're interested, but we may be getting into diminishing returns at this point - I already feel like I've used a lot of your time.

Alex Miller (Clojure team)17:01:35

the latter is https://clojure.org/releases/tools, might want to install latest (1.11.1.1435), might have fixed something there since

Alex Miller (Clojure team)17:01:03

the specific shell you're using may also affect this

Rachel Westmacott17:01:42

I updated Clojure to 1435, no change.

Rachel Westmacott17:01:02

I don't think I've done anything strange to my shell, it should be fairly vanilla. But I'm running Ubuntu rather than Mac...?

Alex Miller (Clojure team)17:01:06

well, may be my environment, I see different things in different directories

Alex Miller (Clojure team)17:01:25

there must be some difference here in how the jvm treats JDK_JAVA_OPTIONS

Alex Miller (Clojure team)17:01:39

also relevant is that depending on whether you have a cached classpath, you may be running from either the first uberjar classpath jvm or the second repl jvm, so you get different behavior on first or nth invocation

Alex Miller (Clojure team)17:01:02

so, definitely shouldn't use JDK_JAVA_OPTIONS regardless

today-i-learned 1
gratitude 1