oraios/serena · error · SolidLSPException
No main Equinox launcher jar found in '{plugins_dir}'. Expec
Error message
No main Equinox launcher jar found in '{plugins_dir}'. Expected file like 'org.eclipse.equinox.launcher_<version>.jar'. Verify the JDTLS extraction is complete and not corrupted. What it means
This SolidLSPException is raised when no main Equinox OSGi launcher jar (org.eclipse.equinox.launcher_<version>.jar) can be found in the JDTLS plugins directory. The launcher jar is the entrypoint JDTLS is started with; its absence means the extraction is incomplete or corrupted. Native launcher fragments (with extra dotted segments after the underscore) are deliberately excluded by the regex.
Source
Thrown at src/solidlsp/language_servers/eclipse_jdtls.py:534
jdtls_readonly_config_path=str(config_dir),
lombok_jar_path=lombok_path,
gradle_path=None,
)
@staticmethod
def _resolve_launcher_jar(plugins_dir: Path) -> Path:
"""
Locates the main Equinox launcher jar in JDTLS's ``plugins/`` directory, excluding
platform-specific native fragments like ``org.eclipse.equinox.launcher.cocoa.macosx.*``.
:return: path to the main launcher jar (e.g. ``org.eclipse.equinox.launcher_1.7.0.v....jar``)
"""
# main launcher matches: org.eclipse.equinox.launcher_<digit>...jar (single underscore,
# immediately followed by version digits — fragments have additional dotted segments).
pattern = re.compile(r"^org\.eclipse\.equinox\.launcher_\d.*\.jar$")
matches = sorted(p for p in plugins_dir.glob("org.eclipse.equinox.launcher_*.jar") if pattern.match(p.name))
if not matches:
raise SolidLSPException(
f"No main Equinox launcher jar found in '{plugins_dir}'. "
f"Expected file like 'org.eclipse.equinox.launcher_<version>.jar'. "
f"Verify the JDTLS extraction is complete and not corrupted."
)
# if multiple versions are present (rare), pick the highest by name
return matches[-1]
@staticmethod
def _resolve_config_dir(jdtls_root: Path) -> Path:
"""
Locates the platform-specific OSGi configuration directory inside the JDTLS root.
:return: path to ``config_<platform>/`` directory matching the current OS/arch
"""
platform_id = PlatformUtils.get_platform_id().value
config_dir_name = JDTLS_CONFIG_DIR_BY_PLATFORM.get(platform_id)
if config_dir_name is None:
raise SolidLSPException(View on GitHub (pinned to 7fcbca7e62)
Solutions
- Re-extract the official jdt-language-server tarball to restore the full plugins/ directory.
- Confirm with 'ls plugins/ | grep equinox.launcher' that a jar like org.eclipse.equinox.launcher_1.x.x.vYYYY.jar exists.
- If a native fragment jar (name with extra dots after underscore) is present but the main jar isn't, the extraction is broken — restore it.
- Disable antivirus interference or re-download if files were quarantined.
- Fall back to default vscode-java VSIX mode by removing jdtls_path/lombok_path.
Example fix
# before: plugins/ missing launcher $ ls /opt/jdtls/plugins | grep launcher org.eclipse.equinox.launcher.cocoa.macosx.x86_64_1.2.900.jar # after: re-extract tar -xzf jdt-language-server-latest.tar.gz -C /opt/jdtls $ ls /opt/jdtls/plugins | grep '^org.eclipse.equinox.launcher_'
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
plugins = Path(jdtls_path).expanduser() / 'plugins'
launchers = [p for p in plugins.glob('org.eclipse.equinox.launcher_*.jar')
if not p.name.split('_')[1].split('.')[0].isdigit() or p.name.count('.') >= 0]
# simple pre-check: at least one non-fragment launcher
assert any(p.name.startswith('org.eclipse.equinox.launcher_') and p.name[len('org.eclipse.equinox.launcher_'):].split('.')[0].isdigit()
for p in plugins.glob('org.eclipse.equinox.launcher_*.jar')), 'main launcher jar missing' Type guard
def has_main_launcher_jar(jdtls_root) -> bool:
import re
from pathlib import Path
pattern = re.compile(r'^org\.eclipse\.equinox\.launcher_\d.*\.jar$')
plugins = Path(jdtls_root) / 'plugins'
return plugins.is_dir() and any(pattern.match(p.name) for p in plugins.glob('org.eclipse.equinox.launcher_*.jar')) Try / catch
try:
ls = SolidLSP(java_config)
except SolidLSPException as e:
if 'No main Equinox launcher jar' in str(e):
reextract_jdtls_tarball(jdtls_path)
ls = SolidLSP(java_config)
else:
raise Prevention
- Verify extraction completeness (file count/jar listing) right after untarring.
- Never delete 'duplicate' equinox launcher jars from plugins/ manually.
- Keep antivirus exclusions for the JDTLS directory to avoid quarantined jars.
- Re-extract from the official snapshot tarball if plugins/ looks modified.
When it happens
Trigger: _resolve_launcher_jar globs plugins_dir for 'org.eclipse.equinox.launcher_*.jar', filters by the main-launcher regex, and raises when no match survives — during upstream JDTLS setup.
Common situations: Interrupted or partial tarball extraction; antivirus quarantined jars; user manually pruned 'duplicate' launcher jars (removing the real one, keeping only fragments); pointing plugins dir at wrong vscode-java subfolder.
Related errors
- BSL Language Server JAR not found at {jar_path} after instal
- Both 'jdtls_path' and 'lombok_path' must be set together in
- Resource paths inside the vscode-java {vscode_java_version}
- Provided jdtls_path '{jdtls_path}' is not an existing direct
- Invalid jdtls_path '{jdtls_path}': 'plugins/' directory not
AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29).
Data as JSON: /api/errors/eaa01973b88f29f9.
Report an issue: GitHub.