Remove hardcoded dependency of SBT on JDK8?

Currently SBT seems to have a harcoded preference for JDK8. See here: https://github.com/NixOS/nixpkgs/blob/360e0fae7e205d3c63a21a11791e15dfa5079cb9/pkgs/development/tools/build-managers/sbt/default.nix#L16. The conf/sbtopts file this is written to is loaded by SBT on start-up, so unless JAVA_HOME is passed as an argument to SBT, JDK8 is used.

As far as I understand it SBT is designed to grab the java it works with from the PATH. So I was very confused when I loaded up JDK11 in nix-shell and SBT still used JDK8, even though which java reported the JDK11 Java.

So my question is: is there a good reason for this hardcoded preference? Because if someone did this with a good reason, or if it is convention or something, I can live with it/work around it. Or should I change this and make a PR with this hardcoding removed? It seems like the current behavior is somewhat unconventional, but that might just be me. (I also thought of sending the package maintainer an e-mail but I wasn’t sure if that’s appropriate so I’m first asking here…)

1 Like

It uses whatever Java gets passed in.

Feel free to sbt.override { jre = pkgs.jdk11; } or whatever is necessary for you.

Hmm, what if I just want SBT to use whatever’s on the path? Now that I see myself typing this, that sounds like it goes against nix’s philosophy… I’ll use your workaround, thanks.

If SBT is like maven; it will defer to JAVA_HOME before taking the Java if uses itself.

For my programs, I set JAVA_HOME in my nix shell to the desired JDK.

This let’s maven run with whatever JDK it uses but compile/run my application with the desired JDK.

You might be interested to know that since https://github.com/NixOS/nixpkgs/pull/89731 it has moved to Java 14 by default.

1 Like

Okay, I’m probably making a very noob mistake (and I should probably have posted this thread in the “Learn” section, sorry), but I can’t get the following to work:

{ pkgs, ... }:
{
  imports = [
    ./vim.nix
  ];

  home.packages = with pkgs; [
    fortune
    xclip
    graphviz
    jdk11
    sbt.override { jre = pkgs.jdk11; }
  ];
}

This file is then imported in my main home.nix. This gives me an error:

error: The option value `home.packages.[definition 1-entry 5]' in `~/commandLine.nix' is not of type `package'.
(use '--show-trace' to show detailed location information)

It looks like the sbt.override line is the problem. I thought .override returned a package, but it looks like I don’t get it after all. Maybe the .override pattern is meant for overlays, but that sounds like a heavyweight example for “just” changing one dependency (maybe I’m underestimating if that’s a big deal or not). Do I need to start using overlays or am I misunderstanding .override?

I also tried referring directly to sbt in <nixpkgs> so I could pass in the arguments for the package manually but I couldn’t get the path right…

EDIT:

I searched and read a bit more about overlays and came up with the following:

{ config, pkgs, ... }:
let sbtOverlay = self: super:
{
  sbt = super.sbt.override { jre = super.jdk11; };
};
in
{
  nixpkgs.overlays = [ sbtOverlay ];
  // rest of config
}

And then in my sub .nix files I just refer to SBT. Not sure what to do now if I want to have differently versioned SBT’s (probably tweak JAVA_HOME), but this works fine for now. If there’s a shorter/more elegant way I’m still very curious to hear.

You need to put parens like this:

{ pkgs, ... }:
{
  imports = [
    ./vim.nix
  ];

  home.packages = with pkgs; [
    fortune
    xclip
    graphviz
    jdk11
    (sbt.override { jre = pkgs.jdk11; })
  ];
}

Otherwise nix parses like this:

{ pkgs, ... }:
{
  imports = [
    ./vim.nix
  ];

  home.packages = with pkgs; [
    fortune
    xclip
    graphviz
    jdk11
    (sbt.override)
    ({ jre = pkgs.jdk11; })
  ];
}

and neither sbt.override nor jre = pkgs.jdk11; } are packages.

2 Likes