Repository navigation
fix(manifest): run Gradle and sbt on a JDK they support - #1665
Open
Martin Torp (mtorp) wants to merge 5 commits into
Open
Martin Torp (mtorp) wants to merge 5 commits into
Martin Torp (mtorp) wants to merge 5 commits into
Conversation
Gradle before 9.1 and sbt before 1.9 do not start on Java 25, and sbt before 1.3 does not start on Java 17. A machine whose default JDK is newer than the project's pinned build tool supports therefore failed to generate Socket facts, even with a suitable JDK installed. Facts generation now reads the Gradle wrapper or sbt version the project pins and, when the current JDK is outside the range that version runs on, runs the build on the newest installed JDK inside it. Installed JDKs are found under the usual JVM directories, SDKMAN, Gradle- and IDE-provisioned JDKs, macOS bundles, and the JAVA_HOME_<release>_<arch> variables CI runners set. A javaHome configured in socket.json still wins, and Maven builds keep the current JDK.
The Gradle and sbt Java ranges now come from one table and one function, compared with semver. JDK discovery reads its search directories and candidates in parallel, and the two test files share their fake JDK and Gradle wrapper fixtures.
A Gradle wrapper set as the bin in socket.json, or passed as a path like ../gradlew, now gets a JDK it supports too. The wrapper version is read from the gradle/wrapper folder next to the script, wherever that script lives. Also reads files through safeReadFile, drops two sbt table rows the lookup never reached, and states the Java 17 threshold as a version like the rest of the table.
Assisted-by: Claude Code:claude-sonnet-5-5
Version detection now asks build-tool.mts whether a bin is the Gradle wrapper, so the wrapper name lives in one place. Also stops exporting three types nothing imports and finds the newest supported Java with findLast.
Martin Torp (mtorp)
marked this pull request as ready for review
October 30, 2026 12:07
Martin Torp (mtorp)
requested a review
from Jeppe Fredsgaard Blaabjerg (jfblaa)
October 30, 2026 12:07
This branch has not been deployed
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.
Older Gradle and sbt versions refuse to start on newer JDKs. So a machine whose default JDK is newer than the project's pinned build tool fails to generate Socket facts, even when a suitable JDK is installed next to it. Managed reachability scans want to move their default JDK to 25, and Gradle 8 projects are where that breaks.
When facts generation runs a Gradle wrapper or sbt build, the CLI now reads the version the project pins and checks it against the JDK in
JAVA_HOME(or thejavaonPATH). If the build tool doesn't run on that JDK, the build runs on the newest installed JDK it does run on, and the CLI logs which one:gradle/wrapper/gradle-wrapper.propertiesand the sbt version fromproject/build.properties. A Gradle wrapper given as thebin, such as../gradlewor an absolute path, is read from thegradle/wrapperfolder next to it. A Gradle onPATH, any other custombinand Maven keep the current JDK.releasefile in the children of/usr/lib/jvm,/usr/lib64/jvm,/usr/javaand/opt/java, in SDKMAN, in~/.gradle/jdksand~/.jdks, in macOSJavaVirtualMachinesbundles, and through theJAVA_HOME_<release>_<arch>variables GitHub and Azure runners set.javaHomefromsocket.jsonis used as is. If no installed JDK fits, the build runs on the current one, as it did before.Where each build tool started and resolved a Guava dependency (Temurin in Docker):
Testing: unit tests for version parsing, ranges, discovery and selection use real temp-dir JDK layouts. A
run.mtstest checks that the spawned build gets the pickedJAVA_HOMEand that a configured one is kept. End to end, I ran the built CLI in an image withJAVA_HOMEset to Temurin 25 and all five JDKs installed.socket manifest gradleon a Gradle 8.14.3 wrapper project ran on 21, andsocket manifest scalaon an sbt 1.5.8 project ran on 17. Both wrote facts containing the dependency. Without this change both builds fail to start on 25.Follow-ups, not in this PR:
languageVersionthat isn't installed..sdkmanrc,.tool-versionsandactions/setup-java.main.Expected reviewer effort: High-level design decisions
Note
Medium Risk
Changes which JDK runs Gradle/sbt manifest builds when the default is incompatible; wrong compatibility tables or discovery could pick a bad JDK, though explicit
javaHome/JAVA_HOMEstill wins.Overview
When generating Socket facts via a Gradle wrapper or pinned sbt build, the CLI now detects a JDK/
JAVA_HOMEmismatch with the project's Gradle or sbt version and, if needed, runs the build on the newest installed JDK that version supports—logging the switch—instead of failing on a default JDK that is too new or too old.A new
java-homehelper reads wrapper/build.propertiesversions, applies Gradle and sbt Java compatibility ranges, discovers JDKs under common install paths and CIJAVA_HOME_*variables, andrunManifestScript/enumerateWorkspacessetJAVA_HOMEon the spawned process when auto-selection applies. Maven, non-wrapper Gradle, and an explicitJAVA_HOMEin options (includingsocket.jsonjavaHome) are unchanged; if no suitable JDK is found, behavior stays as before.isBuildToolWrapperwas added so Gradle version detection only runs for wrapper invocations. Unit and integration-style tests cover parsing, ranges, discovery, selection, and spawned env.Reviewed by Cursor Bugbot for commit 8b2e827. Configure here.