{"record":{"id":"5144aef7f111c1a9","repo":"oraios/serena","slug":"jdtls-requires-jdk-jdtls-min-jdk-version-but","errorCode":null,"errorMessage":"JDTLS requires JDK {JDTLS_MIN_JDK_VERSION}+ but '{java_exe}' is JDK {major_version} (located via {source}, java.home={real_jdk_home}). Install a newer JDK and update ls_specific_settings.java.java_home or JAVA_HOME.","messagePattern":"JDTLS requires JDK (.+?)\\+ but '(.+?)' is JDK (.+?) \\(located via (.+?), java\\.home=(.+?)\\)\\. Install a newer JDK and update ls_specific_settings\\.java\\.java_home or JAVA_HOME\\.","errorType":"exception","errorClass":"SolidLSPException","httpStatus":null,"severity":"error","filePath":"src/solidlsp/language_servers/eclipse_jdtls.py","lineNumber":618,"sourceCode":"                    log.warning(f\"JAVA_HOME='{env_home}' invalid (no '{candidate}'), falling back to PATH.\")\n\n            if java_exe is None:\n                java_in_path = shutil.which(\"java\")\n                if java_in_path is None:\n                    raise SolidLSPException(\n                        \"Could not locate a Java installation for JDTLS. \"\n                        \"Set ls_specific_settings.java.java_home, set JAVA_HOME environment variable, \"\n                        f\"or ensure 'java' is on PATH. Required: JDK {JDTLS_MIN_JDK_VERSION}+.\"\n                    )\n                java_exe = java_in_path\n                source = f\"PATH ({java_in_path})\"\n\n            # interrogate the JVM for its real java.home and version (single source of truth)\n            real_jdk_home, major_version = EclipseJDTLS.DependencyProvider._inspect_java(java_exe)\n\n            # validate version\n            if major_version < JDTLS_MIN_JDK_VERSION:\n                raise SolidLSPException(\n                    f\"JDTLS requires JDK {JDTLS_MIN_JDK_VERSION}+ but '{java_exe}' is JDK {major_version} \"\n                    f\"(located via {source}, java.home={real_jdk_home}). \"\n                    f\"Install a newer JDK and update ls_specific_settings.java.java_home or JAVA_HOME.\"\n                )\n            log.info(f\"Resolved JDK {major_version} via {source}; java.home={real_jdk_home}; java_exe={java_exe}.\")\n\n            # prefer to use bin/java from the *real* JDK home (so JDTLS subprocesses that read JAVA_HOME\n            # find a consistent layout); only fall back to the original locator if the real-home variant\n            # is missing for some reason.\n            real_java = str(Path(real_jdk_home) / \"bin\" / java_exe_name)\n            if os.path.exists(real_java):\n                java_exe = real_java\n\n            return real_jdk_home, java_exe\n\n        @staticmethod\n        def _inspect_java(java_exe: str) -> tuple[str, int]:\n            \"\"\"","sourceCodeStart":600,"sourceCodeEnd":636,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/solidlsp/language_servers/eclipse_jdtls.py#L600-L636","documentation":"SolidLSPException thrown by _resolve_system_jdk when the located Java executable reports a major version below JDTLS_MIN_JDK_VERSION (17). The library interrogates the JVM directly via -XshowSettings:properties and refuses to start JDTLS on an unsupported JDK, reporting where the java came from and its real java.home.","triggerScenarios":"_resolve_system_jdk finds a java executable (via java_home setting, JAVA_HOME, or PATH) but _inspect_java returns major_version < 17; raised from _setup_from_existing_install.","commonSituations":"System default java is JDK 8/11; JAVA_HOME points at an old JDK used by a legacy build; a wrapper script shadows a newer JDK; macOS /usr/bin/java stub resolving to an outdated JVM.","solutions":["Install JDK 17+ and point ls_specific_settings.java.java_home (or JAVA_HOME) at it","Check the current version: <java_exe> -version, and upgrade if below 17","Remove a stale JAVA_HOME entry that shadows the newer JDK","Update PATH so a modern JDK's bin directory comes first"],"exampleFix":"// before\nexport JAVA_HOME=/usr/lib/jvm/java-8-openjdk\n// after\nexport JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64","handlingStrategy":"validation","validationCode":"import subprocess, re\ndef jdk_major(java_exe: str) -> int | None:\n    out = subprocess.run([java_exe, \"-version\"], capture_output=True, text=True)\n    m = re.search(r'version \"(\\d+)', out.stderr + out.stdout)\n    return int(m.group(1)) if m else None\n\nassert (jdk_major(java_exe) or 0) >= 17, \"JDTLS needs JDK 17+\"","typeGuard":"def is_jdk17_plus(java_exe: str) -> bool:\n    major = jdk_major(java_exe)\n    return major is not None and major >= 17","tryCatchPattern":"try:\n    ls = start_jdtls()\nexcept SolidLSPException as e:\n    if \"requires JDK\" in str(e):\n        os.environ[\"JAVA_HOME\"] = \"/usr/lib/jvm/java-21\"  # switch to modern JDK\n        ls = start_jdtls()\n    else:\n        raise","preventionTips":["Pin JAVA_HOME or java_home to a JDK 17+ installation in all environments","Check 'java -version' in CI setup steps before running Java-dependent features","Keep legacy JDKs off PATH or ordered after the modern one","Note the error's java.home report to identify which JDK is actually being picked"],"tags":["java","jdk","version-check","compatibility"],"backgroundTag":"unsupported-java-version","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}