This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-01-04
Channels
- # announcements (1)
- # babashka (1)
- # beginners (84)
- # biff (22)
- # calva (9)
- # cider (8)
- # clerk (5)
- # clj-kondo (10)
- # clojure (105)
- # clojure-europe (13)
- # clojure-nl (1)
- # clojure-norway (44)
- # clojure-spec (4)
- # clojure-uk (6)
- # clojuredesign-podcast (36)
- # cursive (13)
- # datomic (24)
- # dev-tooling (8)
- # emacs (8)
- # hyperfiddle (4)
- # jobs (1)
- # leiningen (2)
- # london-clojurians (1)
- # lsp (5)
- # malli (6)
- # membrane (11)
- # nyc (1)
- # off-topic (14)
- # other-languages (8)
- # pathom (25)
- # pedestal (2)
- # re-frame (4)
- # releases (1)
- # remote-jobs (1)
- # shadow-cljs (98)
- # sql (5)
- # squint (1)
- # tools-deps (38)
- # vim (8)
- # xtdb (11)
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.
(apologies if this is the wrong channel - it's hard to know where exactly the issue lies as I don't yet understand it)
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).
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
)
you can also use -J
to pass env vars on the clj
command line without using any env vars
Thank you very much. This is all very helpful.
(and interesting)
oh, that's actually yet another way to do it :)
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")'
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.
I would expect the quoting to be the same for the two env vars (but different for -J)
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
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")
I think the only change I have there is the env var name.
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?
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.
I guess the former is handled by the jdk directly and the latter is passed on by the clj script so they are different
in fact, I think the clojure
script may be missing double quotes where that happens
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.
I think you need the \" but should remove the inner ' '
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.
I don't think so
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
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
(separately, the clj script is missing quotes for passing $JAVA_OPTS, but that's irrelevant in these particular examples)
at this point it may become relevant what you have for java -version
and clj --version
/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.
the latter is https://clojure.org/releases/tools, might want to install latest (1.11.1.1435), might have fixed something there since
the specific shell you're using may also affect this
I updated Clojure to 1435, no change.
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...?
well, may be my environment, I see different things in different directories
there must be some difference here in how the jvm treats JDK_JAVA_OPTIONS
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