fix(java): import a Gradle build on a JDK its Gradle runs on when no version is declared (#3181)

Without a Project JDK and without a Java version the build declares, the jdtls Gradle import ran on jdtls's own runtime, which an older Gradle cannot run on, so every non-JDK dependency stayed unresolved. When the Gradle version is known, the import now uses the newest installed JDK that Gradle supports; a Project JDK, Gradle JVM or declared toolchain still wins.

Fixes #2681
This commit is contained in:
l0ng-ai
2026-11-13 22:17:50 +08:00
committed by GitHub
parent 85f4ffb67c
commit 2acd5cf479
+21 -1
View File
@@ -377,6 +377,11 @@ fn gradle_run_jdk<'a>(
})
}
/// The newest installed JDK that Gradle `gradle` runs on.
fn newest_gradle_jdk(gradle: (u32, u32), installed: &[crate::java::Jdk]) -> Option<&crate::java::Jdk> {
installed.iter().filter(|jdk| gradle_supports_java(gradle, jdk.major)).max_by_key(|jdk| jdk.major)
}
/// Default environment shared by Gradle model builds and Run configurations.
pub fn gradle_build_env(
root: &Path,
@@ -493,7 +498,17 @@ pub fn configure_gradle_runtime(cfg: &mut LanguageServerConfig, root: &Path, bui
.any(|f| build_dir.join(f).is_file());
let env = if gradle_build {
let command = gradle_command(root, build_dir, s);
gradle_build_env(root, build_dir, &command.to_string_lossy(), s, None)
let command = command.to_string_lossy();
let mut env = gradle_build_env(root, build_dir, &command, s, None);
// No Project JDK and no Java version the build declares: jdtls would import on its own
// runtime, which an older Gradle cannot run on. Use an installed JDK this Gradle supports.
if !env.contains_key("JAVA_HOME")
&& let Some(gradle) = gradle_distribution_version(build_dir, &command)
&& let Some(jdk) = newest_gradle_jdk(gradle, &crate::java::installed_jdks())
{
env.insert("JAVA_HOME".into(), jdk.home.to_string_lossy().into_owned());
}
env
} else {
gradle_env(root, s, Default::default())
};
@@ -2028,6 +2043,11 @@ mod gradle_runtime_tests {
assert_eq!(gradle_run_jdk(Some(21), None, &installed, None).unwrap().major, 21);
assert_eq!(gradle_run_jdk(Some(19), None, &installed, None).unwrap().major, 21);
assert!(gradle_run_jdk(None, None, &installed, None).is_none());
// The Java import of a build that declares no Java version still needs a JVM its Gradle runs on.
assert_eq!(newest_gradle_jdk((8, 4), &installed).unwrap().major, 17);
assert_eq!(newest_gradle_jdk((7, 2), &installed).unwrap().major, 11);
assert_eq!(newest_gradle_jdk((9, 1), &installed).unwrap().major, 25);
assert!(newest_gradle_jdk((9, 0), &installed[4..]).is_none());
}
#[test]