nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1# Gradle {#gradle}
2
3Gradle is a popular build tool for Java/Kotlin. Gradle itself doesn't
4currently provide tools to make dependency resolution reproducible, so
5nixpkgs has a proxy designed for intercepting Gradle web requests to
6record dependencies so they can be restored in a reproducible fashion.
7
8## Building a Gradle package {#building-a-gradle-package}
9
10Here's how a typical derivation will look like:
11
12```nix
13stdenv.mkDerivation (finalAttrs: {
14 pname = "pdftk";
15 version = "3.3.3";
16
17 src = fetchFromGitLab {
18 owner = "pdftk-java";
19 repo = "pdftk";
20 rev = "v${finalAttrs.version}";
21 hash = "sha256-ciKotTHSEcITfQYKFZ6sY2LZnXGChBJy0+eno8B3YHY=";
22 };
23
24 nativeBuildInputs = [ gradle ];
25
26 # if the package has dependencies, mitmCache must be set
27 mitmCache = gradle.fetchDeps {
28 inherit (finalAttrs) pname;
29 data = ./deps.json;
30 };
31
32 # this is required for using mitm-cache on Darwin
33 __darwinAllowLocalNetworking = true;
34
35 gradleFlags = [ "-Dfile.encoding=utf-8" ];
36
37 # defaults to "assemble"
38 gradleBuildTask = "shadowJar";
39
40 # will run the gradleCheckTask (defaults to "test")
41 doCheck = true;
42
43 installPhase = ''
44 mkdir -p $out/{bin,share/pdftk}
45 cp build/libs/pdftk-all.jar $out/share/pdftk
46
47 makeWrapper ${jre}/bin/java $out/bin/pdftk \
48 --add-flags "-jar $out/share/pdftk/pdftk-all.jar"
49
50 cp ${finalAttrs.src}/pdftk.1 $out/share/man/man1
51 '';
52
53 meta.sourceProvenance = with lib.sourceTypes; [
54 fromSource
55 binaryBytecode # mitm cache
56 ];
57})
58```
59
60To update (or initialize) dependencies, run the update script via
61something like `$(nix-build -A <pname>.mitmCache.updateScript)`
62(`nix-build` builds the `updateScript`, `$(...)` runs the script at the
63path printed by `nix-build`).
64
65If your package can't be evaluated using a simple `pkgs.<pname>`
66expression (for example, if your package isn't located in nixpkgs, or if
67you want to override some of its attributes), you will usually have to
68pass `pkg` instead of `pname` to `gradle.fetchDeps`. There are two ways
69of doing it.
70
71The first is to add the derivation arguments required for getting the
72package. Using the pdftk example above:
73
74```nix
75{ lib
76, stdenv
77# ...
78, pdftk
79}:
80
81stdenv.mkDerivation (finalAttrs: {
82 # ...
83 mitmCache = gradle.fetchDeps {
84 pkg = pdftk;
85 data = ./deps.json;
86 };
87})
88```
89
90This allows you to `override` any arguments of the `pkg` used for
91the update script (for example, `pkg = pdftk.override { enableSomeFlag =
92true };`), so this is the preferred way.
93
94The second is to create a `let` binding for the package, like this:
95
96```nix
97let self = stdenv.mkDerivation {
98 # ...
99 mitmCache = gradle.fetchDeps {
100 pkg = self;
101 data = ./deps.json;
102 };
103}; in self
104```
105
106This is useful if you can't easily pass the derivation as its own
107argument, or if your `mkDerivation` call is responsible for building
108multiple packages.
109
110In the former case, the update script will stay the same even if the
111derivation is called with different arguments. In the latter case, the
112update script will change depending on the derivation arguments. It's up
113to you to decide which one would work best for your derivation.
114
115## Update Script {#gradle-update-script}
116
117The update script does the following:
118
119- Build the derivation's source via `pkgs.srcOnly`
120- Enter a `nix-shell` for the derivation in a `bwrap` sandbox (the
121 sandbox is only used on Linux)
122- Set the `IN_GRADLE_UPDATE_DEPS` environment variable to `1`
123- Run the derivation's `unpackPhase`, `patchPhase`, `configurePhase`
124- Run the derivation's `gradleUpdateScript` (the Gradle setup hook sets
125 a default value for it, which runs `preBuild`, `preGradleUpdate`
126 hooks, fetches the dependencies using `gradleUpdateTask`, and finally
127 runs the `postGradleUpdate` hook)
128- Finally, store all of the fetched files' hashes in the lockfile. They
129 may be `.jar`/`.pom` files from Maven repositories, or they may be
130 files otherwise used for building the package.
131
132`fetchDeps` takes the following arguments:
133
134- `attrPath` - the path to the package in nixpkgs (for example,
135 `"javaPackages.openjfx22"`). Used for update script metadata.
136- `pname` - an alias for `attrPath` for convenience. This is what you
137 will generally use instead of `pkg` or `attrPath`.
138- `pkg` - the package to be used for fetching the dependencies. Defaults
139 to `getAttrFromPath (splitString "." attrPath) pkgs`.
140- `bwrapFlags` - allows you to override bwrap flags (only relevant for
141 downstream, non-nixpkgs projects)
142- `data` - path to the dependencies lockfile (can be relative to the
143 package, can be absolute). In nixpkgs, it's discouraged to have the
144 lockfiles be named anything other `deps.json`, consider creating
145 subdirectories if your package requires multiple `deps.json` files.
146
147## Environment {#gradle-environment}
148
149The Gradle setup hook accepts the following environment variables:
150
151- `mitmCache` - the MITM proxy cache imported using `gradle.fetchDeps`
152- `gradleFlags` - command-line flags to be used for every Gradle
153 invocation (this simply registers a function that uses the necessary
154 flags).
155 - You can't use `gradleFlags` for flags that contain spaces, in that
156 case you must add `gradleFlagsArray+=("-flag with spaces")` to the
157 derivation's bash code instead.
158 - If you want to build the package using a specific Java version, you
159 can pass `"-Dorg.gradle.java.home=${jdk}"` as one of the flags.
160- `gradleBuildTask` - the Gradle task (or tasks) to be used for building
161 the package. Defaults to `assemble`.
162- `gradleCheckTask` - the Gradle task (or tasks) to be used for checking
163 the package if `doCheck` is set to `true`. Defaults to `test`.
164- `gradleUpdateTask` - the Gradle task (or tasks) to be used for
165 fetching all of the package's dependencies in
166 `mitmCache.updateScript`. Defaults to `nixDownloadDeps`.
167- `gradleUpdateScript` - the code to run for fetching all of the
168 package's dependencies in `mitmCache.updateScript`. Defaults to
169 running the `preBuild` and `preGradleUpdate` hooks, running the
170 `gradleUpdateTask`, and finally running the `postGradleUpdate` hook.
171- `gradleInitScript` - path to the `--init-script` to pass to Gradle. By
172 default, a simple init script that enables reproducible archive
173 creation is used.
174 - Note that reproducible archives might break some builds. One example
175 of an error caused by it is `Could not create task ':jar'. Replacing
176 an existing task that may have already been used by other plugins is
177 not supported`. If you get such an error, the easiest "fix" is
178 disabling reproducible archives altogether by setting
179 `gradleInitScript` to something like `writeText
180 "empty-init-script.gradle" ""`
181- `enableParallelBuilding` / `enableParallelChecking` /
182 `enableParallelUpdating` - pass `--parallel` to Gradle in the
183 build/check phase or in the update script. Defaults to true. If the
184 build fails for mysterious reasons, consider setting this to false.
185- `dontUseGradleConfigure` / `dontUseGradleBuild` / `dontUseGradleCheck`
186 \- force disable the Gradle setup hook for certain phases.
187 - Note that if you disable the configure hook, you may face issues
188 such as `Failed to load native library 'libnative-platform.so'`,
189 because the configure hook is responsible for initializing Gradle.