Auto-detecting Java installations

Some applications need to discover Java installations.

NixOS already populates JAVA_HOME and adds java/javac to the PATH, which is a great start.

However, some applications want to discover not just the ‘current’ Java, but all installed/available JRE/JDK’s. Unfortunately, there’s no nice convention on how to make their JAVA_HOME's discoverable. The result of this is that applications are resorting to terrible hacks

In the long run, I would like those terrible hacks to also discover JDK’s installed on NixOS.

Perhaps we should think about providing a not-too-terrible way to discover JRE/JDK’s in NixOS, and then add support for that approach to those tools?

One way I could imagine would be to introduce a JAVA_HOMES environment variable to hold a colon-separated list, and have each JDK package contribute its JAVA_HOME to that list (just like it contributes its bin directory to the PATH). Would that make sense?

Why do you want to have multiple JDK’s available at the same time?

Things like:

  • Build on JDK8, but test that the resulting artifact also works on JDK11
  • Build on JDK11 but target JDK8, and also test the artifacts indeed work with JDK8
  • Build part of your artifact targeting JDK8, but another part targeting JDK11

I agree these are ‘niche’ use cases, and we shouldn’t support them when this comes at a prohibitive cost. But exposing them through a JAVA_HOMES environment variable seems fairly non-intrusive, and would be rather useful at least to me ;).

As a workaround to make this work with sbt for now I have in my shell.nix:

{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  JAVA_8_HOME = "${pkgs.jdk}/lib/openjdk";
  JAVA_11_HOME = "${pkgs.jdk11}/lib/openjdk";

And then in an .sbt file:

fullJavaHomes in ThisBuild := fullJavaHomes.value + (("1.8", file(sys.env("JAVA_8_HOME")))) + (("11", file(sys.env("JAVA_11_HOME"))))

Not ideal, but gets the job done. I would still love to see a nice convention so we can solve this ‘upstream’ (in nix/sbt) instead of for each local build.