There’s a proper way and there’s a hack. Let’s start with the hack.
There are two handy commands to find “where is binary x” packaged for most Linux distros,
command -v (bash builtin) and
which. You can find where
java is using those, and that binary should be inside the jdk.
You can then trace back to the actual location of the jdk. See for example on my machine:
tlater ~ $ command -v java
zsh: correct 'java' to '.java' [nyae]? n
tlater ~ $ ls /etc/profiles/per-user/tlater/bin/java
tlater ~ $ ls -l /etc/profiles/per-user/tlater/bin/java
lrwxrwxrwx 70 root 1 Jan 1970 /etc/profiles/per-user/tlater/bin/java -> /nix/store/hmv0pigrv2nrfrdp89i0h4gwhg904cw9-home-manager-path/bin/java
tlater ~ $ ls -l /nix/store/hmv0pigrv2nrfrdp89i0h4gwhg904cw9-home-manager-path/bin/java
lrwxrwxrwx 74 root 1 Jan 1970 /nix/store/hmv0pigrv2nrfrdp89i0h4gwhg904cw9-home-manager-path/bin/java -> /nix/store/953r540bqwrjbwc21aaxhr265h2jsw1j-openjdk-8u272-b10-jre/bin/java
tlater ~ $ ls /nix/store/953r540bqwrjbwc21aaxhr265h2jsw1j-openjdk-8u272-b10-jre/
bin lib nix-support
In other words, my jdk currently lives under
/nix/store/953r540bqwrjbwc21aaxhr265h2jsw1j-openjdk-8u272-b10-jre/, and in practice I can use that path for a selection like this.
Why is this a hack? Well, nix packages are different from other distro packages. Other distros, when you update your package, will completely overwrite the contents of the old package. If, for the sake of argument, your jdk on another distro is installed as
/opt/jdk, and you update your jdk with the package manager, the package will be overwritten and the new one will be available under
/opt/jdk, so your IDE config doesn’t need to change for the new JDK. If your IDE doesn’t work with that version, it will break, and there’s no way to make it work again, because other packages on your system will rely on the updated java.
When using nix, nix simply downloads the new version to a new nix store path. You’ll end up with both versions, and nix just updates all references it controls to the new location. This is the basic principle behind nix, and why it’s cool, because you can have multiple versions of a package without things becoming incompatible. The problem is, nix doesn’t control your IDE config, so it can’t update the reference there - so if you manually insert the path into that box, the next time you run
nix-collect-garbage your IDE will no longer be able to find your jdk.
You could use this hack and just update the jdk in the future whenever it breaks. Not that bad for a single config.
But what’s the proper way? Well, ideally the IDE would be able to find the jdk installation automatically. There is a somewhat standard environment variable for “JDK location” called
$JAVA_HOME. You can make nix set that variable for you automatically: programs.java.enable. You would then set the jdk version used with programs.java.package (which defaults to the “default” jdk version on NixOS, currently 11 I believe). I’d recommend also removing java from my
environment.systemPackages to make sure nothing gets confused between different versions (and never, ever use
nix-env -i or
nix-env -iA on NixOS, those commands are for using nix on other distros).
If you set that, rebuild your system and then reboot, hopefully IDEA supports that variable and shouldn’t need to be configured any further. This support page suggests it does, but it’s not very explicit about what it means, so who knows: https://intellij-support.jetbrains.com/hc/en-us/articles/206544879
Incidentally, if you want to use a different JDK for your IDE than for your system, you can use a nix shell with the particular jdk you want to use, especially combined with something like direnv.
nix-shell will automatically set the variable. You may want to use jetbrains.jdk for example.
All of that said, I thought this IDE came with a bundled jdk, and you don’t need to specify a separate one?