Always symlinking the latest "jdk" to a certain path

Since IntelliJ keeps forgetting the JDK I set for a project, I was thinking: could I automatically link the latest jdk (meaning whatever I get when I nix-shell -p jdk) to a certain path? For example /opt/jdk or something?

For my user, I can certainly do nix-build -A jdk '<nixpkgs>' --out-link ~/jdk, but that doesn’t get updated as the system upgrades.

For NixOS you can check how /bin/sh is staticly created:

1 Like

If you install OpenJDK system-wide on NixOS, you should be able to use /run/current-system/sw/lib/openjdk/ ;).


I use this approach:

  environment.etc = with pkgs; {
    "jdk".source = jdk;
    "jdk8".source = jdk8;
    "jdk12".source = jdk12;

which gives:

$ ls -l /etc/jdk*
lrwxrwxrwx 1 root root 15 Jun  3 07:38 /etc/jdk -> /etc/static/jdk
lrwxrwxrwx 1 root root 17 Jun  3 07:38 /etc/jdk12 -> /etc/static/jdk12
lrwxrwxrwx 1 root root 16 Jun  3 07:38 /etc/jdk8 -> /etc/static/jdk8

$ ls -l /etc/static/jdk*
lrwxrwxrwx 3 root root 60 Dec 31  1969 /etc/static/jdk -> /nix/store/16fgzv12dnlwbblxrmnf132jb2y2jg5v-openjdk-8u212-ga
lrwxrwxrwx 2 root root 57 Dec 31  1969 /etc/static/jdk12 -> /nix/store/z8mdrhyp1jxn9jxwsl2qkkw59qj9md0j-openjdk-12-ga
lrwxrwxrwx 3 root root 60 Dec 31  1969 /etc/static/jdk8 -> /nix/store/16fgzv12dnlwbblxrmnf132jb2y2jg5v-openjdk-8u212-ga

@Jerith Thanks, this is the method I now use!

I am using

  system.extraSystemBuilderCmds = ''
                                                             mkdir -p $out/pkgs
                                                             ln -s ${pkgs.gcc7                     } $out/pkgs/gcc7
                                                             ln -s ${pkgs.gcc8                     } $out/pkgs/gcc8
    ${lib.optionalString (pkgs.gcc9        or null != null) "ln -s ${pkgs.gcc9                     } $out/pkgs/gcc9"}
                                                             ln -s ${pkgs.pkgsi686Linux.oraclejre6 } $out/pkgs/oraclejre6
                                                             ln -s ${pkgs.oraclejdk8               } $out/pkgs/oraclejdk8
                                                             ln -s ${pkgs.openjdk8                 } $out/pkgs/openjdk8
                                                             ln -s ${pkgs.openjdk11                } $out/pkgs/openjdk11
                                                             ln -s ${pkgs.openjdk12                } $out/pkgs/openjdk12
                                                             ln -s ${pkgs.jvmci8                   } $out/pkgs/jvmci8
                                                             ln -s ${pkgs.graalvm8-ce              } $out/pkgs/graalvm8-ce
    ${lib.optionalString (pkgs.graalvm8-ee or null != null) "ln -s ${pkgs.graalvm8-ee              } $out/pkgs/graalvm8-ee"}

                                                             ln -s ${pkgs.gtk3                     } $out/pkgs/gtk3
                                                             ln -s ${                 } $out/pkgs/

This gives 3 certain locations which correspond to <nixpkgs-booted>, <nixpkgs-current> and <nixpkgs-next>:


A NixOS module which creates the code for system.extraSystemBuilderCmds

The motivation to have a module is to gather requests for stable path from other modules.

For example, if another module needs jdk on stable path it can use
system.stable.packages."myjdk" = jdk8 to land it at /run/current-system/pkgs/myjdk
instead of contributing to dll hell with environment.systemPackages = [ jdk8 ]

system.stable.selectors is for mass-matching, for example
system.stable.selectors = [ "(open|oracle)jdk[0-9]+" ]; will make links for all JDK’s available in currently used nixpkgs (so these paths are not truly stable, upgrading nixpkgs could delete paths to deprecated JDKs)


I just nix-env -iA nixpkgs.openjdk11 and used /home/$USER/.nix-profile/lib/openjdk as stable path.

Is there any other solution these days? /etc seems a inconvenient location for me and the module @volth posted does not exist anymore.

if you’re managing your user’s environment with nix (such as with home-manager). You can always set JAVA_HOME. (probably also do-able with nixos)

@johnringer I think doing this via an environment variable is not possible as my applications needs a static path and cannot access it via an environment variable.

@Jerith 's suggestion would probably be best then

I use Home Manager and install all my packages as user packages. I’ve done the following to link packages into my home directory with Home Manager:

home.file = {
  # Stable SDK symlinks
  "SDKs/Android".source = "${android-sdk}/share/android-sdk";
  "SDKs/Java/17".source = pkgs.jdk17.home;
  "SDKs/Java/11".source = pkgs.jdk11.home;
  "SDKs/Java/8".source = pkgs.jdk8.home;
Hosted by Flying Circus.