Package version arguments vs. generic package arguments

I have recently seen PRs, where the commonly-used pattern:


{ jdk, ...}:


somepackage = {
  jdk = jdk8;

is replaced by, or not used in favor of, another commonly-used pattern:

{ jdk8, ...}:

  jdk = jdk8;
in mkDerivation {
  # ...
  buildInputs = [ jdk8 ];
  # ...

I wonder if there is any consensus on which pattern is preferred. Personally, I dislike the latter pattern, because it makes overriding packages less intuitive. E.g.

somepackage.override { jdk = jdk11; };


somepackage.override { jdk8 = jdk11; };

Moreover, if the jdk8 attribute is later changed to jdk11, overrides that a user may have become invalid, because the jdk8 attribute is not available anymore.

I can see that for packages that are very strongly tied to particular versions of a runtime or library, it makes sense to hardcode the dependency. However, newer versions of e.g. Java runtimes or CUDA toolkits are generally backwards compatible.

Any opinions?


That’s mostly what happened in #89731. I tried to override as much as possible in all-packages.nix, and only change the derivation file when I got a build error with the new jdk. In some other cases it was infeasible to override from all-package.nix, e.g. in chromium, also in that case I changed the derivation file.

Sorry, I probably shouldn’t have cited this PR (which is very useful), so I have removed the link.

It’s something I just noticed in various PRs that both patterns occur and reviewers sometimes ask people to modify derivations in one direction or the other.

I found this thread while researching examples for a good way to do the jdk version in the clojure derivation more configurable. In this particular case, I want to default to jdk11 (since clojure officially only supports java LTS releases).

I see pros and cons on both proposed patterns, I’d like to know what do you think about a 3rd pattern:

{ pkgs 
, jdkPkg ? pkgs.pkg11  
, ...}:

mkDerivation {
  # ...
  buildInputs = [ jdkPkg ];
  # ...

IMO that makes clear that there is a preferred jdk version, but overriding packages is still intuitive and changes to the version will not break user overrides. Also, it makes unnecessary to update all-packages.nix

This is also my experience, and because of this, my personal preference is to:

  • generally: use jdk in default.nix (pointing to the latest JDK)
  • when a package does not work with the latest JDK: use jdk8 (or whatever) in the package’s default.nix.

This helps us detect problems as soon as possible, and reduces spreading information between all-packages.nix and default.nix.

You’re right that, for packages that need a particular JDK version, overriding the JDK becomes a bit awkward - but that should be the exception rather than the norm anyway.

(I’m not strongly opposed to using jdk in default.nix and overriding it as needed in all-packages.nix, though. By the way, for python we should explicitly use python3 as discussed in Should `python` point to python3? - #7 by jonringer)

This recently also came up in Retirement of old OpenJDK releases? and there doesn’t seem to be consensus about it, btw :wink: .

There is no consensus and it’s an easy thing to bikeshed about.

I have an opinion (as stated in the first post). But I care more about having a rule than it being my preferred rule, since now PR submitters will get comments (or not) based on which reviewer looks at a PR. This also happens in somewhat similar cases (e.g. should the darwin frameworks that a derivation uses be enumerated in all-packages.nix or can a derivation just use e.g. darwin.Security).

Or perhaps we don’t need a rule, but we should not hold up PRs based on such preferences.

1 Like

Totally agree, but it seems difficult to find a consensus.

I want to create a PR for the clojure derivation, but now I’m even more unsure about the pattern to use. BTW, do you see problems with the 3rd pattern I proposed in my previous post?

In general, I favor putting the jdk = jdk8 in all-packages.nix, since it makes sprints such as easier to handle.

Other then that, the very uncommon (for AFAIK) pattern with pkgs imported to the derivation, might introduce an unjustified increase in evaluation time - I can’t find a metric for that, but in general using pkgs inside a derivation feels bad to me.