Skip to content

Commit cc22d5c

Browse files
author
Uriel Curiel
committed
fix(windows): quote paths in JDTLS and Lombok arguments
When the user path contains spaces (e.g. `C:\Users\User Name`), the Java process fails to start with a `ClassNotFoundException` because the paths in arguments are split by the shell/process. This change: - Quotes the path for `-Dosgi.sharedConfiguration.area` in JDTLS launch args on Windows. - Quotes the path for `-javaagent` (Lombok) on Windows. - Adds unit tests to verify path escaping behavior across platforms. Closes #150
1 parent 13de31f commit cc22d5c

2 files changed

Lines changed: 67 additions & 2 deletions

File tree

src/java.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,37 @@ impl Java {
143143
}
144144
}
145145

146+
fn format_lombok_agent_arg(path: &str, os: zed::Os) -> String {
147+
if os == zed::Os::Windows {
148+
format!("-javaagent:\"{path}\"")
149+
} else {
150+
format!("-javaagent:{path}")
151+
}
152+
}
153+
154+
#[cfg(test)]
155+
mod tests {
156+
use super::*;
157+
use zed_extension_api::Os;
158+
159+
#[test]
160+
fn test_format_lombok_agent_arg_windows() {
161+
let path = "C:\\Users\\User Name\\lombok.jar";
162+
let arg = format_lombok_agent_arg(path, Os::Windows);
163+
assert_eq!(arg, format!("-javaagent:\"{path}\""));
164+
}
165+
166+
#[test]
167+
fn test_format_lombok_agent_arg_unix() {
168+
let path = "/Users/username/lombok.jar";
169+
let arg = format_lombok_agent_arg(path, Os::Mac);
170+
assert_eq!(arg, format!("-javaagent:{path}"));
171+
172+
let arg_linux = format_lombok_agent_arg(path, Os::Linux);
173+
assert_eq!(arg_linux, format!("-javaagent:{path}"));
174+
}
175+
}
176+
146177
impl Extension for Java {
147178
fn new() -> Self
148179
where
@@ -288,7 +319,10 @@ impl Extension for Java {
288319
self.lombok_jar_path(language_server_id, &configuration, worktree)?;
289320
let canonical_lombok_jar_path = path_to_string(current_dir.join(lombok_jar_path))?;
290321

291-
Some(format!("-javaagent:{canonical_lombok_jar_path}"))
322+
Some(format_lombok_agent_arg(
323+
&canonical_lombok_jar_path,
324+
zed::current_platform().0,
325+
))
292326
} else {
293327
None
294328
};

src/jdtls.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub fn build_jdtls_launch_args(
7272
"-Dosgi.checkConfiguration=true".to_string(),
7373
format!(
7474
"-Dosgi.sharedConfiguration.area={}",
75-
path_to_string(shared_config_path)?
75+
escape_path_if_needed(path_to_string(shared_config_path)?, current_platform().0)
7676
),
7777
"-Dosgi.sharedConfiguration.area.readOnly=true".to_string(),
7878
"-Dosgi.configuration.cascaded=true".to_string(),
@@ -353,3 +353,34 @@ fn get_shared_config_path(jdtls_base_directory: &Path) -> PathBuf {
353353
};
354354
jdtls_base_directory.join(config_to_use)
355355
}
356+
357+
fn escape_path_if_needed(path: String, os: Os) -> String {
358+
if os == Os::Windows {
359+
format!("\"{}\"", path)
360+
} else {
361+
path
362+
}
363+
}
364+
365+
#[cfg(test)]
366+
mod tests {
367+
use super::*;
368+
use zed_extension_api::Os;
369+
370+
#[test]
371+
fn test_escape_path_if_needed_windows() {
372+
let path = "C:\\Users\\User Name\\Projects\\zed-extension-java".to_string();
373+
let escaped = escape_path_if_needed(path.clone(), Os::Windows);
374+
assert_eq!(escaped, format!("\"{}\"", path));
375+
}
376+
377+
#[test]
378+
fn test_escape_path_if_needed_unix() {
379+
let path = "/Users/username/Projects/zed-extension-java".to_string();
380+
let escaped = escape_path_if_needed(path.clone(), Os::Mac);
381+
assert_eq!(escaped, path);
382+
383+
let escaped_linux = escape_path_if_needed(path.clone(), Os::Linux);
384+
assert_eq!(escaped_linux, path);
385+
}
386+
}

0 commit comments

Comments
 (0)