fix(java): say when a configured JDK path no longer exists

A JDK chosen in Settings › Languages & Frameworks › Java that was later
removed (e.g. a version manager replaced it on upgrade) was reported as
"is not a JDK home", which reads as if the folder had the wrong layout.
The language server JDK error and the project JDK warning now say the path
does not exist and how to fix it.
This commit is contained in:
l0ng-ai committed 2026-11-02 10:49:16 +08:00
1 parent 239753df9f
commit 8ca7efc411
2 files changed
+20 -6

No files matched your search

+14 -5
View File
@@ -78,7 +78,7 @@ fn jdk_setting(root: &Path, value: &str) -> Option<Result<crate::java::Jdk, Path
/// The project JDK (`languages.java.jdk`), else the JDK the project pins for mise / asdf.
pub fn project_jdk(root: &Path, s: &Settings) -> Option<crate::java::Jdk> {
match jdk_setting(root, &s.languages.java.jdk) {
Some(jdk) => jdk.inspect_err(|p| tracing::warn!("project JDK {} is not a JDK home", p.display())).ok(),
Some(jdk) => jdk.inspect_err(|p| tracing::warn!("project JDK {}", not_a_jdk(p))).ok(),
None => pinned::pinned_install(root, Tool::Java).and_then(|(dir, _)| pinned::jdk_in_install(&dir)),
}
}
@@ -89,10 +89,19 @@ pub fn jdtls_jdk(root: &Path, s: &Settings) -> Result<Option<crate::java::Jdk>,
match jdk_setting(root, &s.languages.java.jdtls_jdk) {
None => Ok(None),
Some(Ok(jdk)) => Ok(Some(jdk)),
Some(Err(p)) => Err(format!(
"The language server JDK {} is not a JDK home (Settings › Languages & Frameworks › Java).",
p.display()
)),
Some(Err(p)) => {
Err(format!("The language server JDK {} (Settings › Languages & Frameworks › Java).", not_a_jdk(&p)))
}
}
}
/// Why the configured JDK path `p` is not used: gone (e.g. a version manager removed
/// it on upgrade) or not a JDK.
fn not_a_jdk(p: &Path) -> String {
if p.exists() {
format!("{} is not a JDK home", p.display())
} else {
format!("{} does not exist; choose another JDK or clear the setting to detect one", p.display())
}
}
+6 -1
View File
@@ -308,8 +308,13 @@ fn jdtls_jdk_setting() {
s.languages.java.jdtls_jdk = "jdk17/bin".into();
assert_eq!(jdtls_jdk(tmp.path(), &s).unwrap().map(|j| j.major), Some(17));
// A chosen path that is not a JDK is an error, not a silent fallback.
s.languages.java.jdtls_jdk = "missing".into();
std::fs::create_dir(tmp.path().join("not-a-jdk")).unwrap();
s.languages.java.jdtls_jdk = "not-a-jdk".into();
assert!(jdtls_jdk(tmp.path(), &s).unwrap_err().contains("is not a JDK home"));
// A JDK removed after it was chosen (a version manager upgraded it) says so.
s.languages.java.jdtls_jdk = "jdk17.0.1".into();
let err = jdtls_jdk(tmp.path(), &s).unwrap_err();
assert!(err.contains("jdk17.0.1 does not exist") && err.contains("Languages & Frameworks › Java"), "{err}");
}
#[test]