A Gradle plugin that generates a comprehensive JSON lockfile containing all dependency coordinates, checksums, download URLs, and repository metadata needed for hermetic (offline, network-isolated) Gradle builds via Hermeto.
Plugin ID: io.github.hermetoproject.gradle-lockfile
Version: 0.3.0-SNAPSHOT (lockfile schema v3)
| Gradle Version | Status | Notes |
|---|---|---|
| 7.0 - 7.1 | Untested | APIs present but not tested |
| 7.2+ | Supported | Tested on 7.2, 7.6.4 |
| 8.x | Supported | Tested on 8.12 |
| 9.x | Supported | Tested on 9.4.1 |
JVM Requirements:
- Plugin requires JDK 11+ at runtime (compiled to JVM target 11)
- Gradle 7.2 requires JDK 8-16 to run (JDK 11 recommended)
- Gradle 7.3+ supports JDK 17+
- Gradle 8.5+ supports JDK 21+
# 1. Generate the init script (run in the lockfile plugin's own project)
./gradlew generateInitScript
# 2. Apply to any Gradle 7.2+ project without modifying its build files
cd /path/to/target-project
./gradlew --no-parallel --init-script /path/to/hermeto-lockfile.gradle generateLockfileAll extension properties are configurable via -PlockfilePropertyName=value flags or
LOCKFILE_UPPER_SNAKE environment variables. For example:
./gradlew --no-parallel --init-script hermeto-lockfile.gradle \
-PlockfileLenientConfigResolution=true \
-PlockfileAllowInternalRepositories=true \
-PlockfileExtraDependencies=org.aspectj:aspectjtools:1.9.25 \
generateLockfile// settings.gradle.kts
pluginManagement {
repositories { gradlePluginPortal() }
}// build.gradle.kts
plugins {
id("io.github.hermetoproject.gradle-lockfile") version "0.3.0"
}
lockfile {
allowInternalRepositories.set(true)
lenientConfigResolution.set(true)
}./gradlew --no-parallel generateLockfileValidated end-to-end against Spring Framework 7.x (Gradle 9.5.0, 27 subprojects):
| Metric | Value |
|---|---|
| Dependencies captured | 1,497 |
| Buildscript dependencies | 190 |
| Platform/BOM POMs | 48 |
| Parent POMs (inheritance chains) | 206 |
| Repositories | 7 |
| Hermetic build result | ./gradlew :spring-beans:build --offline — 41s, 38 tasks, zero network access |
| Data | Notes |
|---|---|
| Group:Artifact:Version | All configurations across all subprojects |
| SHA-256 checksums | Computed from Gradle cache files |
| Download URLs | HEAD-verified against declared repositories |
| Repository IDs | Which repo serves each artifact |
| Classifiers | -gradle813, -sources, etc. |
| Types | jar, pom, module |
| Platform/BOM POMs | Version-constraint-only components from dependency graph |
| Parent POM chains | For inherited property resolution (${project.version}, etc.) |
| Dependency tree | Optional nested children per entry |
| Conflict losers | Artifacts that lost version negotiation |
| Plugin markers | Gradle Plugin Portal ID→implementation mappings |
| Buildscript deps | Separate array from main dependencies |
| Classifier companions | Plain JAR alongside classified variants |
.module metadata |
Gradle Module Metadata for KMP variant resolution |
| Extra dependencies | Task-time artifacts via extraDependencies |
| Capability | Native lockfile | verification-metadata.xml | This plugin |
|---|---|---|---|
| Repository URLs | No | No | Yes |
| Checksums | No | Yes | Yes |
| BOM/platform deps | No | No | Yes |
| Single command, no build.gradle changes | No | No | Yes (init script) |
| Classifier variants | No | Yes | Yes |
| Dependency tree | No | No | Yes |
| Parent POM chains | No | No | Yes |
Resolves artifacts through Gradle's dependency resolution API, performs parallel HEAD
requests against declared Maven repositories, computes checksums from locally cached
files, then writes the lockfile. source field: "resolution-api".
The task:
- Collects repositories declared in the project (project-declared repos first, Maven Central and Plugin Portal as fallbacks).
- Resolves all configurations across
rootProject.allprojects(main and buildscript). - buildSrc auto-scan — parses
buildSrc/build.gradle[.kts]for additional coordinates. - Lenient resolution — retries failed configurations with
artifactView { lenient(true) }whenlenientConfigResolution = true. - Extra dependencies — resolves
extraDependenciesGAV coordinates from cache. - Platform/BOM capture — walks
resolutionResult.allComponentsfor constraint-only components; adds their POMs. - Resolves conflict losers when
includeConflictLosers = true. - Classifier companion probing — probes for plain JARs alongside classified variants.
- Module metadata probing — probes for
.moduleand.pomfiles per unique GAV. - Parent POM chain walking — walks
<parent>elements in all collected POMs; adds parent POMs from cache for inherited property resolution. - Parallel HEAD requests to verify download URLs.
- Checksum computation from cached files.
- Writes lockfile.
Uses an existing gradle/verification-metadata.xml as the source of checksums instead
of re-resolving. Includes tamper detection: re-checksums cached artifacts against the
XML values. source field: "verification-metadata".
Generates a Groovy init script that applies the plugin to any Gradle 7.2+ project
without modifying build files. Template-based with @@PLUGIN_VERSION@@ injection.
Configure inside a lockfile { } block or via -P flags / env vars:
| Property | Type | Default | Description |
|---|---|---|---|
outputFile |
String |
"gradle-lockfile.json" |
Output path relative to root project dir |
checksumAlgorithm |
String |
"SHA-256" |
Hash algorithm |
maxHeadConcurrency |
Int |
10 |
Max parallel HEAD requests |
maxArtifacts |
Int |
10_000 |
Abort if artifact count exceeds this |
maxRepositories |
Int |
20 |
Abort if repository count exceeds this |
allowHttpRepositories |
Boolean |
false |
Allow non-HTTPS repository URLs |
allowInternalRepositories |
Boolean |
false |
Allow non-public/internal URLs |
includeConflictLosers |
Boolean |
true |
Include version-conflict losers |
includeDependencyTree |
Boolean |
true |
Populate children on each entry |
maxConflictLosersToResolve |
Int |
50 |
Cap on conflict losers resolved |
maxGraphNodes |
Int |
10_000 |
Cap on dependency graph nodes |
verificationMetadataFile |
String |
"gradle/verification-metadata.xml" |
Input for verification mode |
excludePatterns |
List<String> |
["io.github.hermetoproject:gradle-lockfile-plugin"] |
Glob patterns to exclude |
repositoryPriority |
List<String> |
[] |
URL substrings to prioritize during resolution |
includeClassifierCompanions |
Boolean |
true |
Probe for plain JAR alongside classified variants |
includeModuleMetadata |
Boolean |
true |
Probe for .module and .pom metadata files |
detectChecksumMismatches |
Boolean |
false |
Compare cache size vs remote Content-Length |
lenientConfigResolution |
Boolean |
false |
Retry failed configs with lenient artifact view |
maxPluginMarkerProbes |
Int |
500 |
Cap on plugin marker HEAD requests |
extraDependencies |
List<String> |
[] |
GAV coordinates for task-time artifacts |
| Scope | Meaning |
|---|---|
compileClasspath, runtimeClasspath, etc. |
Standard Gradle configuration |
buildscript, buildSrc |
Build infrastructure dependencies |
companion |
Plain JAR probed alongside a classified variant |
metadata |
.module or .pom metadata file |
platform |
BOM/platform component (version constraints only) |
parent-pom |
Parent POM from Maven inheritance chain |
extra |
Manually specified via extraDependencies |
conflict-loser |
Artifact that lost version negotiation |
Gradle 9.5 enforces exclusive locks for cross-project configuration resolution during
parallel execution. Use --no-parallel when generating lockfiles for multi-project
builds. The plugin warns if parallel execution is detected.
-
Transitive BOM imports — BOMs imported via
<dependencyManagement><scope>import</scope>in other POMs are not captured if not in the Gradle cache. These are resolved by Gradle at the constraint level without downloading the POM files. -
Task-time resolution — Dependencies resolved by plugins at task execution time (e.g.,
aspectjtoolsby the freefair aspectj plugin) require manualextraDependenciesconfiguration. This is a workaround for Gradle's lack of a task-time resolution capture API. -
Configuration cache — Not compatible with Gradle's configuration cache. Designed for one-shot lockfile generation, not cached incremental builds.
-
Kotlin implementation — Currently implemented in Kotlin. A Java 21 port is planned for consistency with the Maven lockfile plugin ecosystem.
./gradlew build # compile + unit tests
./gradlew test # unit tests only
./gradlew functionalTest # functional (integration) testsToolchain: JDK 25 for compilation, JVM 11 bytecode target.
Apache License 2.0