How to find where is Java JDK installed in my NixOS?

Hi,

I have NixOS running and this is my config file.

Even though I have a narrow experience with NixOS/Nix and Java, I am trying to run a Java application. The instructions of the application indicate the installation of the packages maven, jdk8, and jetbrains.idea-community. The installation seems to be successful. For instance,

[pedro@system:~]$ java -version
openjdk version "1.8.0_272"
OpenJDK Runtime Environment (build 1.8.0_272-b10)
OpenJDK 64-Bit Server VM (build 25.272-b10, mixed mode)


At some point on the tutorial, after running IDEA, I need to configure JDK. On the tutorial, the instructor uses a Windows machine and simply finds where Java is installed making a pointer.

When I try to reproduce his moves, I cannot find in which folder Java is installed in my NixOS:

And:

Where should I look for?

Since I did the installation changing the config file and doing a sudo nixos-rebuild switch, I am kind of lost here.

Thanks.

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
/etc/profiles/per-user/tlater/bin/java
tlater ~ $ ls /etc/profiles/per-user/tlater/bin/java
/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?

3 Likes

I got this little module, it definitely has some issues but I did not bother fixing em nixfiles/runtimes.nix at 2b2abcd07ede0df56360a8cda50a919a65864f8c · gytis-ivaskevicius/nixfiles · GitHub

TL;DR: it symlinks required runtimes of my choosing to /nix