Propagate JAVA_TOOL_OPTIONS to the KtLint Worker Daemon process - #1112
Closed
geirh-nav wants to merge 1 commit into
Closed
Propagate JAVA_TOOL_OPTIONS to the KtLint Worker Daemon process#1112geirh-nav wants to merge 1 commit into
geirh-nav wants to merge 1 commit into
Conversation
Gradle does not forward the JAVA_TOOL_OPTIONS environment variable to forked worker processes by default, unlike other forked JVMs such as Test task executors. This breaks tooling that relies on JVM flags injected via JAVA_TOOL_OPTIONS (e.g. sandboxing/monitoring tools that require -Djava.net.preferIPv4Stack=true to be active in every forked JVM). Re-propagate JAVA_TOOL_OPTIONS explicitly into the Worker Daemon process environment when it is present in the environment running Gradle, matching the behavior of Test task executors. Adds a functional test asserting the option reaches the forked worker process, and documents the behavior in the README. Fixes JLLeitschuh#1110
This was referenced Aug 12, 2026
Owner
|
This seems like a bug in Gradle, not in downstream plugins. Do you have an issue open against http://github.com/gradle/gradle? |
markus-photoncycle
pushed a commit
to markus-photoncycle/cplt
that referenced
this pull request
Aug 14, 2026
…dboxed builds (navikt#170) ## Problem Reported by user: `./gradlew ktlintFormat` fails under cplt even with `allow_localhost_any = true`: ``` org.gradle.internal.remote.internal.ConnectException: Could not connect to server [... port:55788, addresses:[/127.0.0.1]] ``` cplt injects `-Djava.net.preferIPv4Stack=true` via `JAVA_TOOL_OPTIONS` (a2199a9) so JVM connections stay pure IPv4 and match SBPL's `localhost:*` filter (which cannot match IPv4-mapped `::ffff:127.0.0.1`). But Gradle plugin workers — WorkerExecutor process isolation, e.g. ktlint-gradle — fork JVMs with explicit `forkOptions {}` and do not reliably propagate the environment. Verified against [ktlint-gradle source](https://github.com/JLLeitschuh/ktlint-gradle/blob/main/plugin/src/main/kotlin/org/jlleitschuh/gradle/ktlint/tasks/BaseKtLintCheckTask.kt#L260): the fork sets `maxHeapSize`/`jvmArgs` but never touches `environment`. The flag is lost, the worker's dual-stack socket produces `::ffff:127.0.0.1`, SBPL denies the connect. SBPL has no primitive for IPv4-mapped matching — this cannot be fixed in the sandbox profile. ## Fix Install a **guarded Gradle init script** at `~/.gradle/init.d/cplt-sandbox.gradle` on sandbox launch (macOS, both agent and exec/shell paths): ```groovy if (System.getenv("__CPLT_WRAPPED") != null) { System.setProperty("java.net.preferIPv4Stack", "true") allprojects { tasks.withType(JavaExec).configureEach { jvmArgs "-Djava.net.preferIPv4Stack=true" } tasks.withType(Test).configureEach { jvmArgs "-Djava.net.preferIPv4Stack=true" } } } ``` - **Guarded by `__CPLT_WRAPPED`** — inert in unsandboxed builds, safe to leave installed - **Idempotent** — rewrites only when content changes; no-op when `~/.gradle` doesn't exist - Covers the daemon itself plus `Test`/`JavaExec` forks ## Honest limitation `WorkerExecutor` process-isolation forks (the exact ktlint-gradle case) have **no public configuration hook** — an init script cannot reach them. Those still require the upstream plugin fix: [JLLeitschuh/ktlint-gradle#1110](JLLeitschuh/ktlint-gradle#1110) / PR [#1112](JLLeitschuh/ktlint-gradle#1112) (`forkOptions { environment("JAVA_TOOL_OPTIONS", ...) }`). This PR narrows the gap (daemon + task forks) and documents the rest; it does not fully replace the plugin fix. ## Tests 3 new unit tests in `src/gradle_init.rs`: env-marker guard, no-op without `~/.gradle`, idempotent write + stale-content refresh. `mise run check` green: fmt, clippy, 260 unit + 698 lib tests. Docs: `known-impacts.md` updated with the failure mode, the init-script mitigation, and the plugin-side fix pattern. (Supersedes the docs-only PR navikt#169.)
Author
|
Good question — no, there wasn't one yet. Filed it now: gradle/gradle#38836 |
Author
|
I actually prefer the fix-it-in-gradle idea, so I'll make a PR for gradle to sort this instead. If they don't want my change I might have to add another PR for this. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #1110
Gradle does not forward the
JAVA_TOOL_OPTIONSenvironment variable to forked worker processes by default, unlike other forked JVMs such asTesttask executors. This breaks tooling that relies on JVM flags injected viaJAVA_TOOL_OPTIONS— for example, sandboxing/monitoring tools that require flags like-Djava.net.preferIPv4Stack=trueto be active in every forked JVM, not just the main Gradle process orTestworkers.This PR re-propagates
JAVA_TOOL_OPTIONSexplicitly into the KtLint Worker Daemon's process environment when it is present in the environment running Gradle, matching the behavior ofTesttask executors. This mirrors the workaround suggested in the issue and verified there by the reporter.Changes
BaseKtLintCheckTask: forwardJAVA_TOOL_OPTIONSfrom the Gradle process environment into the Worker Daemon'sforkOptionswhen set.README.md: document the new automatic behavior.CHANGELOG.md: add an entry under[Unreleased].KtlintPluginTest: add a functional test that setsJAVA_TOOL_OPTIONSviaGradleRunner.withEnvironmentand asserts the JVM's "Picked up JAVA_TOOL_OPTIONS" startup diagnostic appears in the forked worker's output, confirming propagation reaches the Worker Daemon (not just the Gradle daemon).Testing
:plugin:compileKotlin/:plugin:compileTestKotlinsucceed.Picked up JAVA_TOOL_OPTIONS: -Dktlint.gradle.test.marker=truefrom the forked KtLint Worker Daemon process, confirming the fix works as intended.main, so it is unrelated to this change). Full test suite execution should be verified via this repository's CI.