Skip to main content
The Root.io Gradle Plugin intercepts dependency resolution and transparently substitutes vulnerable dependencies with Root-patched versions from 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

Installation

The plugin is published to the Gradle Plugin Portal. Apply the plugin in build.gradle.kts:
If your pluginManagement block explicitly lists repositories, make sure gradlePluginPortal() is included:

Option 2: Root.io Maven Repository

Add the Root.io Gradle Plugin repository to settings.gradle.kts:
Apply the plugin in build.gradle.kts:

Option 3: Local Maven Repository

For testing or air-gapped environments:
Then add 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 run make publish:
This publishes both the plugin JAR and the Gradle plugin marker artifact (io.root.patcher:io.root.patcher.gradle.plugin) that Gradle requires for plugins {} block resolution.

Consuming

Add the Artifactory repository to pluginManagement in your settings.gradle.kts:
Then apply the plugin as usual in 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 reaching pkg.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:
  1. Query Root.io API for patches on your declared dependencies
  2. Substitute patched versions if available
  3. Register pkg.root.io/maven/ as a Maven repository
  4. Cache results locally at .gradle/rootio-cache/

Configuration

Configure the plugin in build.gradle.kts:

Configuration Properties

API Key Resolution

The plugin resolves the API key in this order (highest priority first):
  1. Build script: rootio { apiKey.set("...") }
  2. Environment variable: export ROOTIO_API_KEY=...
  3. JVM system property: systemProp.ROOTIO_API_KEY=... in ~/.gradle/gradle.properties
  4. .env file: ROOTIO_API_KEY=... in project root
Keep your API key out of source control. Use environment variables or JVM system properties for CI/CD.

Multi-Project Setup

Apply the plugin once at the root and propagate to all subprojects:
Run the build:
All subprojects will automatically use Root-patched dependencies.

Ignoring patch versions

If a specific Root.io patch version causes a regression, you can exclude it. The ignore list is sent to the Root.io API with every request — the server skips the excluded version and returns the best available alternative. Example: commons-lang3 was patched to 3.12.0-root.io.5 but it broke your build. Ignore it to fall back to 3.12.0-root.io.4:
The API will respond with 3.12.0-root.io.4 instead.

Three ways to configure ignores (all merged together)

1. .rootioignore file — place in the project root directory, one entry per line:
2. Build scriptrootio { ignore = [...] }:
3. Gradle property-Prootio.ignore=... (comma-separated), useful for one-off builds:
The entry format is group:artifact@patch-version (exact match, case-sensitive).
Changing the ignore list for a dependency automatically invalidates any cached result for that dependency, so the API is re-queried with the updated list.

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
To clear the cache:

Detailed Flow

  1. Plugin applies to your project and creates the rootio {} configuration extension
  2. API key resolution happens in priority order (build script → env var → system property → .env)
  3. Root.io Maven repository is registered automatically with credentials
  4. Resolution hooks are installed on every resolvable configuration
  5. For each dependency, the plugin:
    • Checks the local cache (.gradle/rootio-cache/) for a valid entry (keyed on coords + ignore list)
    • If cache miss, queries Root.io API (/v3/analyze/maven) with the dependency and the ignore list
    • Substitutes the dependency coordinates if a patch is available
    • Logs the patching decision
  6. Gradle resolves the patched version from pkg.root.io/maven/

Troubleshooting

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