From 2acd5cf479a757947733b4e131e76a9d833ecd5e Mon Sep 17 00:00:00 2001 From: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com> Date: Fri, 13 Nov 2026 22:17:50 +0800 Subject: [PATCH] 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 --- crates/ide-sdk/src/apply.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/crates/ide-sdk/src/apply.rs b/crates/ide-sdk/src/apply.rs index 6ddf178c1..12dce10c3 100644 --- a/crates/ide-sdk/src/apply.rs +++ b/crates/ide-sdk/src/apply.rs @@ -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]