{"record":{"id":"7950308509090446","repo":"oraios/serena","slug":"could-not-parse-java-home-from-java-exe-output","errorCode":null,"errorMessage":"Could not parse java.home from '{java_exe}' output. This usually means '{java_exe}' is not a valid JDK installation. First lines of output: {output.strip().splitlines()[:5]}","messagePattern":"Could not parse java\\.home from '(.+?)' output\\. This usually means '(.+?)' is not a valid JDK installation\\. First lines of output: (.+?)","errorType":"exception","errorClass":"SolidLSPException","httpStatus":null,"severity":"error","filePath":"src/solidlsp/language_servers/eclipse_jdtls.py","lineNumber":660,"sourceCode":"            \"\"\"\n            try:\n                # both -XshowSettings:properties and -version write to stderr by convention\n                result = subprocess_run(\n                    [java_exe, \"-XshowSettings:properties\", \"-version\"],\n                    capture_output=True,\n                    text=True,\n                    timeout=15,\n                    check=False,\n                )\n            except (OSError, subprocess.TimeoutExpired) as exc:\n                raise SolidLSPException(f\"Failed to run '{java_exe} -XshowSettings:properties -version': {exc}\") from exc\n\n            output = (result.stderr or \"\") + \"\\n\" + (result.stdout or \"\")\n\n            # parse java.home from \"    java.home = /path/to/jdk\"\n            home_match = re.search(r\"java\\.home\\s*=\\s*(.+)\", output)\n            if not home_match:\n                raise SolidLSPException(\n                    f\"Could not parse java.home from '{java_exe}' output. \"\n                    f\"This usually means '{java_exe}' is not a valid JDK installation. \"\n                    f\"First lines of output: {output.strip().splitlines()[:5]}\"\n                )\n            real_home = home_match.group(1).strip()\n\n            # parse major version from version line: 'openjdk version \"21.0.2\"' or 'java version \"21.0.2\"'\n            version_match = re.search(r'version \"(\\d+)(?:\\.\\d+)*\"', output)\n            if not version_match:\n                raise SolidLSPException(\n                    f\"Could not parse Java version from '{java_exe}' output. \"\n                    f\"Required: JDK {JDTLS_MIN_JDK_VERSION}+. \"\n                    f\"First lines of output: {output.strip().splitlines()[:5]}\"\n                )\n            major = int(version_match.group(1))\n            return real_home, major\n\n        @classmethod","sourceCodeStart":642,"sourceCodeEnd":678,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/solidlsp/language_servers/eclipse_jdtls.py#L642-L678","documentation":"SolidLSPException thrown by _inspect_java when the output of 'java -XshowSettings:properties -version' contains no 'java.home = ...' line. This normally means the executable is not a real JDK/JVM, so the library cannot determine the true JDK home and aborts rather than guessing.","triggerScenarios":"_resolve_system_jdk/_resolve_java -> _inspect_java where the combined stderr+stdout lacks a java.home property line - e.g. the 'java' resolved is a wrapper script, a JDK uninstaller stub, or prints unrelated text.","commonSituations":"PATH 'java' is a shim (sdkman/jabba wrapper misconfigured); a dummy stub binary like /usr/bin/java on minimal Linux without a real JVM; output locale/format changes breaking expectations; antivirus truncating output.","solutions":["Run '<java_exe> -XshowSettings:properties -version' manually and inspect the output","Replace the shim/stub with a real JDK and update java_home/JAVA_HOME accordingly","Reinstall the JDK if its output is corrupted","Set ls_specific_settings.java.java_home directly to a known-good JDK home to bypass PATH discovery"],"exampleFix":"// before\n$ which java\n/usr/bin/java  # distro stub that prints 'no java runtime present'\n// after\njava_home: /usr/lib/jvm/temurin-21-jdk-amd64  # real JDK home","handlingStrategy":"validation","validationCode":"import subprocess, re\ndef java_home_parseable(java_exe: str) -> bool:\n    r = subprocess.run([java_exe, \"-XshowSettings:properties\", \"-version\"],\n                       capture_output=True, text=True, timeout=15)\n    return bool(re.search(r\"java\\.home\\s*=\\s*(.+)\", (r.stderr or \"\") + (r.stdout or \"\")))","typeGuard":"def looks_like_real_jvm(java_exe: str) -> bool:\n    out = probe(java_exe)  # stderr+stdout of -XshowSettings:properties -version\n    return \"java.home\" in out and \"java.version\" in out","tryCatchPattern":"try:\n    ls = start_jdtls()\nexcept SolidLSPException as e:\n    if \"Could not parse java.home\" in str(e):\n        replace_stub_with_real_jdk()  # e.g. install temurin-21 and set java_home\n        ls = start_jdtls()\n    else:\n        raise","preventionTips":["Avoid shims/wrappers (sdkman, jabba, distro stubs) on PATH for service accounts","Set java_home explicitly to a real JDK home to bypass PATH discovery","On minimal Linux images, install a real JRE/JDK rather than relying on /usr/bin/java stub","Inspect the first output lines included in the error to identify the culprit binary"],"tags":["java","jvm-probe","output-parsing","broken-jdk"],"backgroundTag":"jvm-probe-output-unparseable","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}