The Root.io Gradle Plugin intercepts dependency resolution and transparently substitutes vulnerable dependencies with Root-patched versions fromDocumentation Index
Fetch the complete documentation index at: https://docs.root.io/llms.txt
Use this file to discover all available pages before exploring further.
pkg.root.io/maven/. You declare the versions you know, and the plugin handles the rest—no changes to your dependency declarations required.
Root.io Gradle Plugin
View the source code, report issues, or contribute to the Root.io Gradle Plugin.
Prerequisites
- Gradle 7.0+
- JDK 11+
- Root.io API key (setup instructions)
Installation
Option 1: Gradle Plugin Portal (Recommended)
The plugin is published to the Gradle Plugin Portal. Apply the plugin inbuild.gradle.kts:
pluginManagement block explicitly lists repositories, make sure gradlePluginPortal() is included:
Option 2: Root.io Maven Repository
Add the Root.io Gradle Plugin repository tosettings.gradle.kts:
build.gradle.kts:
Option 3: Local Maven Repository
For testing or air-gapped environments:mavenLocal() to your pluginManagement repositories:
Option 4: Private JFrog Artifactory
Publish and consume the plugin through your own JFrog Artifactory instance - useful when you need full control over the registry or want to keep builds air-gapped from the public internet.Publishing
Set the following environment variables and runmake publish:
io.root.patcher:io.root.patcher.gradle.plugin) that Gradle requires for plugins {} block resolution.
Consuming
Add the Artifactory repository topluginManagement in your settings.gradle.kts:
build.gradle.kts:
Using JFrog as a Proxy for pkg.root.io
If your organization routes all artifact traffic through an internal proxy, you can also point the plugin at your JFrog instance for resolving patched artifacts - instead of reachingpkg.root.io directly.
In JFrog, create a remote Maven repository with the remote URL set to https://pkg.root.io/maven and configure your Root.io API key as the upstream password. JFrog will handle authentication to pkg.root.io on behalf of your builds - individual developers never need a Root.io API key.
In your build.gradle.kts, override pkgUrl and supply JFrog credentials via pkgUsername/pkgPassword:
pkgUsername/pkgPassword control only where patched artifacts are downloaded from, not where the plugin itself is resolved.How It Works
When you run a build, the plugin will:- Query Root.io API for patches on your declared dependencies
- Substitute patched versions if available
- Register
pkg.root.io/maven/as a Maven repository - Cache results locally at
.gradle/rootio-cache/
Configuration
Configure the plugin inbuild.gradle.kts:
Configuration Properties
| Property | Default | Description |
|---|---|---|
apiKey | - | Root.io API key (see API Key Resolution). Also used as a fallback password for the default pkg.root.io Maven repository when pkgUsername/pkgPassword are not set. |
apiUrl | https://api.root.io | Root.io API base URL |
pkgUrl | https://pkg.root.io/maven | Maven repository URL from which patched artifacts are resolved. Override this when routing through a proxy (see Option 4). |
pkgUsername | - | Username for the pkg Maven repository. When set together with pkgPassword, takes precedence over apiKey for repository authentication. |
pkgPassword | - | Password for the pkg Maven repository. When set together with pkgUsername, takes precedence over apiKey for repository authentication. |
ttlHours | 24 | Cache TTL in hours (0 disables caching) |
maxRetries | 3 | Max retry attempts for transient API failures |
retryBaseDelayMs | 1000 | Base delay (ms) for exponential backoff |
allowInsecurePkgRepo | false | Allow plain HTTP for package repo (test/local only) |
API Key Resolution
The plugin resolves the API key in this order (highest priority first):- Build script:
rootio { apiKey.set("...") } - Environment variable:
export ROOTIO_API_KEY=... - JVM system property:
systemProp.ROOTIO_API_KEY=...in~/.gradle/gradle.properties .envfile:ROOTIO_API_KEY=...in project root
Multi-Project Setup
Apply the plugin once at the root and propagate to all subprojects:Caching
The plugin caches Root.io API responses locally at.gradle/rootio-cache/ to avoid repeated network calls.
The cache is not used when:
- The cached response is older than the TTL (default: 24 hours)
ttlHours.set(0)is configured (caching disabled)- A dependency is queried for the first time
- The cache directory has been manually cleared
Detailed Flow
- Plugin applies to your project and creates the
rootio {}configuration extension - API key resolution happens in priority order (build script → env var → system property →
.env) - Root.io Maven repository is registered automatically with credentials
- Resolution hooks are installed on every resolvable configuration
- For each dependency, the plugin:
- Checks the local cache (
.gradle/rootio-cache/) for a valid entry - If cache miss, queries Root.io API (
/v3/analyze/maven) for patches - Substitutes the dependency coordinates if a patch is available
- Logs the patching decision
- Checks the local cache (
- Gradle resolves the patched version from
pkg.root.io/maven/
Troubleshooting
| Issue | Solution |
|---|---|
401 Unauthorized from Root.io API | Verify ROOTIO_API_KEY is set correctly (see API Key Resolution) |
404 Not Found for patched artifact | Confirm the patched version exists in pkg.root.io/maven/ (check Root.io dashboard) |
| Plugin not applying patches | Check Gradle console output for [Root.io] log messages. Ensure plugin is applied before dependencies are declared. |
| Network timeouts | Increase retryBaseDelayMs and maxRetries in the rootio {} block |
| Cache is stale | Delete .gradle/rootio-cache/ or set ttlHours.set(0) to disable caching |
ResolutionStrategy conflicts | Root.io plugin uses eachDependency hooks. Ensure no other plugins conflict with dependency resolution. |
| Multi-project builds not patching subprojects | Verify apply(plugin = "io.root.patcher") is in the subprojects {} block |
If you encounter issues, check the Gradle build output for
[Root.io] prefixed log messages. Run with --info or --debug for detailed output: ./gradlew build --info