835: Add an LS-specific settings use_system_java_home, gradle_wrapper_enabled and gradle_java_home

* fixes serena startup in cases where projects have a gradle wrapper which requires a specific JRE
This commit is contained in:
Thibault Kruse authored and Dominik Jain committed 2026-02-24 14:03:25 +01:00
1 parent 1e89449f40
commit 8c2f303636
2 files changed
+61 -6

No files matched your search

+21
View File
@@ -281,6 +281,27 @@ Notes:
- `GOFLAGS` (from the environment you start Serena in) may also affect the Go build context. Prefer `buildFlags` for tags.
- Build context changes are only picked up when `gopls` starts. After changing `gopls_settings` (or relevant env vars like `GOFLAGS`), restart the Serena process (or server) that hosts the Go language server, or use your client's "Restart language server" action if it causes `gopls` to restart.
#### Java (`eclipse.jdt.ls`)
The following settings are supported for the Java language server:
| Setting | Default | Description |
|---|---|---|
| `maven_user_settings` | `~/.m2/settings.xml` | Path to Maven `settings.xml` |
| `gradle_user_home` | `~/.gradle` | Path to Gradle user home directory |
| `gradle_wrapper_enabled` | `false` | Use the project's Gradle wrapper (`gradlew`) instead of the bundled Gradle distribution. Enable this for projects with custom plugins or repositories. |
| `gradle_java_home` | `null` | Path to the JDK used by Gradle. When unset, Gradle uses the bundled JRE. |
| `use_system_java_home` | `false` | Use the system's `JAVA_HOME` environment variable for JDTLS itself. Enable this if your project requires a specific JDK vendor or version for Gradle's JDK checks. |
Example for a project with custom Gradle plugins and JDK requirements:
```yaml
ls_specific_settings:
java:
gradle_wrapper_enabled: true
use_system_java_home: true
```
#### Kotlin
Serena uses [JetBrains' Kotlin Language Server](https://github.com/Kotlin/kotlin-lsp) for Kotlin support.
+40 -6
View File
@@ -49,8 +49,9 @@ class EclipseJDTLS(SolidLanguageServer):
You can configure the following options in ls_specific_settings (in serena_config.yml):
- maven_user_settings: Path to Maven settings.xml file (default: ~/.m2/settings.xml)
- gradle_user_home: Path to Gradle user home directory (default: ~/.gradle)
Note: Gradle wrapper is disabled by default. Projects will use the bundled Gradle distribution.
- gradle_wrapper_enabled: Whether to use the project's Gradle wrapper (default: false)
- gradle_java_home: Path to JDK for Gradle (default: null, uses bundled JRE)
- use_system_java_home: Whether to use the system's JAVA_HOME for JDTLS itself (default: false)
Example configuration in ~/.serena/serena_config.yml:
```yaml
@@ -60,6 +61,9 @@ class EclipseJDTLS(SolidLanguageServer):
# maven_user_settings: 'C:\\Users\\YourName\\.m2\\settings.xml' # Windows (use single quotes!)
gradle_user_home: "/home/user/.gradle" # Unix/Linux/Mac
# gradle_user_home: 'C:\\Users\\YourName\\.gradle' # Windows (use single quotes!)
gradle_wrapper_enabled: true # set to true for projects with custom plugins/repositories
gradle_java_home: "/path/to/jdk" # set to override Gradle's JDK
use_system_java_home: true # set to true to use system JAVA_HOME for JDTLS
```
"""
@@ -346,7 +350,17 @@ class EclipseJDTLS(SolidLanguageServer):
return cmd
def create_launch_command_env(self) -> dict[str, str]:
return {"syntaxserver": "false", "JAVA_HOME": self.runtime_dependency_paths.jre_home_path}
use_system_java_home = self._custom_settings.get("use_system_java_home", False)
if use_system_java_home:
system_java_home = os.environ.get("JAVA_HOME")
if system_java_home:
log.info(f"Using system JAVA_HOME for JDTLS: {system_java_home}")
return {"syntaxserver": "false", "JAVA_HOME": system_java_home}
else:
log.warning("use_system_java_home is set but JAVA_HOME is not set in environment, falling back to bundled JRE")
java_home = self.runtime_dependency_paths.jre_home_path
log.info(f"Using bundled JRE for JDTLS: {java_home}")
return {"syntaxserver": "false", "JAVA_HOME": java_home}
def _get_initialize_params(self, repository_absolute_path: str) -> InitializeParams:
"""
@@ -404,6 +418,27 @@ class EclipseJDTLS(SolidLanguageServer):
gradle_user_home = None
log.info(f"Gradle user home not found at default location ({default_gradle_home}), will use JDTLS defaults")
# Gradle wrapper: default to False to preserve existing behaviour
gradle_wrapper_enabled = self._custom_settings.get("gradle_wrapper_enabled", False)
log.info(
f"Gradle wrapper {'enabled' if gradle_wrapper_enabled else 'disabled'} (configurable via ls_specific_settings -> java -> gradle_wrapper_enabled)"
)
# Gradle Java home: default to None, which means the bundled JRE is used
gradle_java_home = self._custom_settings.get("gradle_java_home")
if gradle_java_home is not None:
if not os.path.exists(gradle_java_home):
error_msg = (
f"Gradle Java home not found: {gradle_java_home}. "
f"Fix: update path in ~/.serena/serena_config.yml (ls_specific_settings -> java -> gradle_java_home), "
f"or remove the setting to use the bundled JRE"
)
log.error(error_msg)
raise FileNotFoundError(error_msg)
log.info(f"Using Gradle Java home from custom location: {gradle_java_home}")
else:
log.info(f"Using bundled JRE for Gradle: {self.runtime_dependency_paths.jre_path}")
initialize_params = {
"locale": "en",
"rootPath": repository_absolute_path,
@@ -609,10 +644,9 @@ class EclipseJDTLS(SolidLanguageServer):
},
"gradle": {
"enabled": True,
"wrapper": {"enabled": False},
"wrapper": {"enabled": gradle_wrapper_enabled},
"version": None,
"home": "abs(static/gradle-7.3.3)",
"java": {"home": "abs(static/launch_jres/21.0.7-linux-x86_64)"},
"offline": {"enabled": False},
"arguments": None,
"jvmArguments": None,
@@ -719,7 +753,7 @@ class EclipseJDTLS(SolidLanguageServer):
gradle_settings = initialize_params["initializationOptions"]["settings"]["java"]["import"]["gradle"] # type: ignore
gradle_settings["home"] = self.runtime_dependency_paths.gradle_path
gradle_settings["java"]["home"] = self.runtime_dependency_paths.jre_path
gradle_settings["java"] = {"home": gradle_java_home if gradle_java_home is not None else self.runtime_dependency_paths.jre_path}
return cast(InitializeParams, initialize_params)
def _start_server(self) -> None: