Hi all,
these days I mostly write code for the JVM using the gradle build system.
When I setup my laptop with NixOS I just wanted to install the JDK and gradle system-wide, e.g. in /etc/nixos/configuration.nix. Tbh, I just found this easier than fiddling around with nix-shell (which I want to learn a bit later once I get to speed with NixOS).
Installing gradle and the JDK is fairly easy, however, a dependency of the project needs JDK 11 or higher - so I added gradle and jdk14 to my systemPackages only to find out that gradle uses a different version of Java, which in this case is Java 8 - and now loading the dependencies classes on runtime fails. After googling for a while I’m almost certain that I need to use the Overlay mechanism.
My question now is how I can solve the problem with gradle precisely - I think I need an overlay for gradle and override it’s build inputs. Sadly, I don’t know enough about Overlays at the moment to write this overlay on my own.
Can anyone provide a hint for me?
I’m thankful for every advice 
Thanks for reading this!
Overlays are useful if you want to change something in pkgs but they are not strictly necessary for this use case – you can just override gradle in place.
Looking at
https://github.com/NixOS/nixpkgs/blob/27da11972d3fd9353f81e94a6549e8a0da40f45d/pkgs/top-level/all-packages.nix#L12201-L12208
that would probably be something like
environment.systemPackages = [
((pkgs.gradleGen.override {
java = jdk15;
}).gradle_latest)
];
I do not see jdk14 in all-packages.nix, though.
Thank you very much for your post!
It isn’t only the correct solution for my specific problem, as it also shows that I confuse overrides with overlays and now I know what to learn next 
Thanks you much, this works well.
Alternative solution installing multiple JDK(s)
As LinuxInstallationSupplier searches also "/opt/java", the following extension of NixOS configuration can be used:
- create custom package
jdkEnv with sub-directories pointing to JDK(s),
- set
environment.pathsToLink to make this path available in /run/current-system/sw/jdks,
- link it to
/opt/java,
- install latest JDK globally as default, otherwise
./gradlew might fail to run.
{ config, pkgs, ... }:
let
jdkEnv = pkgs.runCommand "jdk-env" {
buildInputs = with pkgs; [
pkgs.openjdk17
pkgs.openjdk21
pkgs.temurin-bin-17
pkgs.temurin-bin-21
];
} ''
mkdir -p $out/jdks
ln -s ${pkgs.openjdk17}/lib/openjdk $out/jdks/openjdk17
ln -s ${pkgs.openjdk21}/lib/openjdk $out/jdks/openjdk21
ln -s ${pkgs.temurin-bin-17} $out/jdks/temurin17
ln -s ${pkgs.temurin-bin-21} $out/jdks/temurin21
'';
in {
environment.pathsToLink = [ "/jdks" ];
environment.systemPackages = [
# to get /run/current-system/sw/jdks/ populated
jdkEnv
# to default java binaries to highest version (instead of 8 or something)
pkgs.temurin-bin
];
system.activationScripts.jdkSymlinks.text = ''
mkdir -p /opt
chmod 755 /opt
ln -sfT /run/current-system/sw/jdks /opt/java
'';
}