Select a default jdk implementation in a nix-shell derivation

Hi,

I would like to experiment with clojure and its build tool leiningen with a modern jdk; the default jdk implementation is currently java 8 and I’m not able to switch to another jdk implementation inside a nix-shell.
I’m using the following default.nix

let
   pkgs = import <nixpkgs> {};
   newPkgs = pkgs // {jdk = pkgs.adoptopenjdk-jre-openj9-bin-11;};
in 
with newPkgs;
stdenv.mkDerivation {
  name = "clojure";
  nativeBuildInputs = [
    jdk
    lumo     
    leiningen
    clojure
  ];
  buildInputs = [
    openssl
    
  ];  
}

when I’m running nix-shell it is using the selected jdk

$ java -version
openjdk version "11.0.3" 2019-04-16
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.3+7)
Eclipse OpenJ9 VM AdoptOpenJDK (build openj9-0.14.0, JRE 11 Linux amd64-64-Bit Compressed References 20190417_202 (JIT enabled, AOT enabled)
OpenJ9   - bad1d4d06
OMR      - 4a4278e6
JCL      - 5cc996a803 based on jdk-11.0.3+7)

but leiningen is still running with java 8

$ lein -version
Leiningen 2.9.1 on Java 1.8.0_212 OpenJDK 64-Bit Server VM

as it is set inside the wrapper script

$ cat `which lein`
#! /nix/store/cinw572b38aln37glr0zb8lxwrgaffl4-bash-4.4-p23/bin/bash -e
export PATH='/nix/store/lhnmfhvw0zlhrd56gp13h2ajbmg51cjh-rlwrap-0.43/bin:/nix/store/d9s1kq1bnwqgxwcvv4zrc36ysnxg8gv7-coreutils-8.30/bin'${PATH:+':'}$PATH
export LEIN_GPG='/nix/store/mqynspckwdp0ymalay32wb7pa7x3hpax-gnupg1compat-2.2.13/bin/gpg'
export JAVA_CMD='/nix/store/gp1avksany5bilwm4vj6nz0vv8cc7wx5-openjdk-8u212-ga/bin/java'
exec -a "$0" "/nix/store/20rpcd8pc7krpfn9ca7p5rgmiwbmgn7r-leiningen-2.9.1/bin/.lein-wrapped"  "${extraFlagsArray[@]}" "$@"

How can I change the default jdk to a different version and have all build tools use the new version?

Thanks

This is where overlays are useful. For instance, this would use the same jdk everywhere:

let
  pkgs = import <nixpkgs> { overlays = [ (self: super: {
    jdk = super.adoptopenjdk-jre-openj9-bin-11;
  }) ]; };
in
with pkgs;
stdenv.mkDerivation {
  name = "clojure";
  nativeBuildInputs = [
    jdk
    lumo
    leiningen
    clojure
  ];
  buildInputs = [
    openssl
  ];
}

You have to be careful that this approach isn’t a mass rebuild (for instance, overriding something like stdenv will mean you must rebuild everything). But for jdk, it works well (the example above rebuilds clojure, leiningen, and lumo).

2 Likes

Perfect, exactly what I was expecting from my configuration.

Thanks!

how would you achive this in a configuration.nix file? I’m always confused by the fact that the syntax differs between nix-shell and .nix files…

Being a complete noob at nix, i came up with this:

newPkgs = with pkgs; { overlays = [ (self: super: {
    jdk = super.adoptopenjdk-jre-openj9-bin-11;
  }) ]; };
   environment.systemPackages = with newPkgs; [
    jdk
  ];

but that gives me the error “undefined variable newPkgs at line such and such”

all my other attempts end up installing java 8 when I need 11 or later

1 Like

I too wonder where one would go to clarify this. Especially with overlays, it seems like the syntax is different…

The syntax of the language does not change.

Only the way how you apply an overlay changes, as you are in a different context.

In home.nix or configuration.nix you need to use nixpkgs.overlays option rather than to overwrite or create a new pkgs variable, which wouldn’t be used in that context anyway.