How does nREPL choose its JVM? I have 24.0.1:
$ java -version
openjdk version "24.0.1" 2025-04-15
OpenJDK Runtime Environment GraalVM CE 24.0.1+9.1 (build 24.0.1+9-jvmci-b01)
OpenJDK 64-Bit Server VM GraalVM CE 24.0.1+9.1 (build 24.0.1+9-jvmci-b01, mixed mode, sharing)
But when I start up an nREPL server for my project:
JAVA_HOME=$(which java) clj -Sdeps '{:deps {cider/cider-nrepl {:mvn/version "0.57.0"}}}' -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware]"
It's picking up some other JDK it found on my system somehow:
;; Connected to nREPL server -
;; CIDER 1.15.1 (Cogne), nREPL 1.3.1
;; Clojure 1.12.1, Java 21.0.7
I would very much like to use a new JVM.> Depending on the OS, there are specialized tools to resolve java home. For example, on MacOS, it is /usr/libexec/java_home
somehow on my system that doesn't work together. I installed Java with sdkman.
borkdude@MBP25-2 ~/dev/eucalypt (games) $ echo $JAVA_HOME
/Users/borkdude/.sdkman/candidates/java/current
borkdude@MBP25-2 ~/dev/eucalypt (games) $ /usr/libexec/java_home
The operation couldn't be completed. Unable to locate a Java Runtime.
Please visit for information on installing Java. SDKMan surely appropriates all Java version management, so it is understandable.
>
> I recently stumbed on a script that only called /usr/libexec/java_home`
eeks, I can't get rid of this quoting thing. sorry.
anyway. the script ignored JAVA_HOME but just called that command. I had to tweak it. Just pointing this out that JAVA_HOME should probably be preferred over anything else?
Well, I would prefer JAVA_HOME when dealing with somebody's else setups, sure
> "/nix/store/qagnl38l96xcbx17ll0v9zswhcl1nqw6-openjdk-21.0.7+6/lib/openjdk"
Back to 21.0.7.
Sorry mate, I'm out of ideas. Try asking in #clojure, there must be Nix folks that've dealt with this before.
Hold on, I was getting too sleepy - it's right there in the docs that JAVA_CMD is higher precedence, let me try that.
JAVA_CMD=/nix/store/8ca2h2dk00iwn725dr46n7zd1j18jvn8-graalvm-ce-24.0.1/bin/java clojure
Clojure 1.12.0
user=> (System/getProperty "java.version")
"24.0.1"
It works!But it wasn't set before, you say?
It wasn't, I'm going to have to add that to my workflow. I honestly don't understand why the PATH java wasn't working, but I won't complain now : )
Thank you for working with me :D
No problem, glad it worked
Good night 👋
I think which java gives you a path to java binary, but JAVA_HOME should point to the dir above.
Depending on the OS, there are specialized tools to resolve java home. For example, on MacOS, it is /usr/libexec/java_home
You can also check https://blog.brunobonacci.com/2020/07/02/switching-between-multiple-jdk-in-emacs/ and https://metaredux.com/posts/2018/11/05/managing-multiple-jdks-on-macos.html
I tried doing JAVA_HOME as the directory above the java binary, but I still get Java 21.0.7 in the nREPL connection message.
I don't really need to change between versions at this point, so I'm just looking for the simplest possible way to get an nREPL on a recent JVM.
There is nothing nREPL specific here. You get the JDK that Clojure gets, and Clojure gets one from JAVA_HOME. Please double-check that the JAVA_HOME you set is the correct one. Show what (System/getenv "JAVA_HOME") returns.
This is what I did to launch it:
JAVA_HOME=/run/current-system/sw/bin clj -Sdeps '{:deps {cider/cider-nrepl {:mvn/version "0.57.0"}}}' -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware]"
Where /run/current-system/sw/bin/java is a symlink (I'm on NixOS):
lrwxrwxrwx 3 root root 70 Dec 31 1969 /run/current-system/sw/bin/java -> /nix/store/8ca2h2dk00iwn725dr46n7zd1j18jvn8-graalvm-ce-24.0.1/bin/java
But the java home from inside the repl is something else.
(System/getProperty "java.home")
;; => "/nix/store/qagnl38l96xcbx17ll0v9zswhcl1nqw6-openjdk-21.0.7+6/lib/openjdk"And (System/getenv "JAVA_HOME") is "/run/current-system/sw/bin".
Wait
Check what's in that directory. Is it a real java binary or a symlink to another file?
Sorry, read your comment now.
You should point JAVA_HOME to the directory that contains stuff like this:
I'm not familiar with how NixOS does things, but maybe there is something there to properly resolve the correct paths to JDK installations
If not, then you can probably write a script that resolves the symlink for java, takes the directory for the real binary, then goes one level higher (there should be no bin/ at the end of JAVA_HOME). And put that script somewhere in .bashrc or what have you
Ok, I've given that a spin. I think I've got the corresponding directory, the java binary is now at ./bin/java relative to the JAVA_HOME path.
(System/getenv "JAVA_HOME")
"/nix/store/8ca2h2dk00iwn725dr46n7zd1j18jvn8-graalvm-ce-24.0.1/"
user> (System/getProperty "java.home")
"/nix/store/qagnl38l96xcbx17ll0v9zswhcl1nqw6-openjdk-21.0.7+6/lib/openjdk"
Still getting the older JVM, though.Can you check in the terminal what's inside /nix/store/8ca2h2dk00iwn725dr46n7zd1j18jvn8-graalvm-ce-24.0.1/?
$ ls /nix/store/8ca2h2dk00iwn725dr46n7zd1j18jvn8-graalvm-ce-24.0.1/
bin conf include jmods legal lib nix-support shareLooks legit
What what's inside /nix/store/qagnl38l96xcbx17ll0v9zswhcl1nqw6-openjdk-21.0.7+6?
I'm confused that the real working JDK path has lib/openjdk at the end
This one is a bit more complex:
ls -l /nix/store/qagnl38l96xcbx17ll0v9zswhcl1nqw6-openjdk-21.0.7+6
total 27
lrwxrwxrwx 5 root root 15 Dec 31 1969 bin -> lib/openjdk/bin
lrwxrwxrwx 5 root root 19 Dec 31 1969 include -> lib/openjdk/include
dr-xr-xr-x 3 root root 4 Dec 31 1969 lib
dr-xr-xr-x 2 root root 4 Dec 31 1969 nix-support
dr-xr-xr-x 2 root root 3 Dec 31 1969 shareIt looks like a bit of this to me:
It's got some soft links, but the ./lib/openjdk path leads to the same place:
ls /nix/store/qagnl38l96xcbx17ll0v9zswhcl1nqw6-openjdk-21.0.7+6/lib/openjdk/
bin conf include jmods legal lib man releaseYou're not wrong : )
I don't understand what clj is doing to find the JVM, though. It's clearly not paying attention to JAVA_HOME
Wait, I think toold.deps has another place it tries to look up java version, it could be that. Let me check
Sent you on a wild goose chase, sorry
So, JAVA_CMD is not set.
In my setup, changing JAVA_HOME updates java and other JDK binaries too.
java on the PATH should be what which java points to, so that should be 24.0.1.
ll $(which java)
lrwxrwxrwx 3 root root 70 Dec 31 1969 /run/current-system/sw/bin/java -> /nix/store/8ca2h2dk00iwn725dr46n7zd1j18jvn8-graalvm-ce-24.0.1/bin/javaTry this
JAVA_HOME='/nix/store/8ca2h2dk00iwn725dr46n7zd1j18jvn8-graalvm-ce-24.0.1/lib/openjdk' clj -e '(System/getProperty "java.home")'