This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
"""Optional Java runtime detection.
|
||||
|
||||
``opendataloader-pdf`` (structured PDF→JSON extraction, see chat_agent.py) is a
|
||||
Python wrapper around a JAVA CLI tool — the first Java dependency anywhere in
|
||||
this app. Same optional-native-binary shape as doc_extract.py::find_soffice:
|
||||
env override → PATH → common install directories → ``None`` if not found.
|
||||
Callers must degrade gracefully — a missing JVM just means that one capability
|
||||
isn't available on this machine, not an error.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
_EXE = "java.exe" if os.name == "nt" else "java"
|
||||
|
||||
# Common JDK/JRE install roots, newest-version subfolder picked first.
|
||||
_COMMON_ROOTS = (
|
||||
r"C:\Program Files\Java",
|
||||
r"C:\Program Files\Eclipse Adoptium",
|
||||
r"C:\Program Files (x86)\Java",
|
||||
"/Library/Java/JavaVirtualMachines",
|
||||
"/usr/lib/jvm",
|
||||
)
|
||||
|
||||
|
||||
def _version_key(path: Path) -> tuple:
|
||||
"""Natural-sort key so "jdk-17..." ranks above "jdk-8..." — a plain string
|
||||
sort ranks '8' > '1' and would pick the OLDER JDK when major-version digit
|
||||
counts differ (e.g. Eclipse Adoptium installs several majors side by side
|
||||
under one root)."""
|
||||
return tuple(int(n) for n in re.findall(r"\d+", path.name))
|
||||
|
||||
|
||||
def find_java() -> str | None:
|
||||
"""Locate a Java launcher (``JAVA_HOME`` → PATH → common install dirs)."""
|
||||
env = os.environ.get("JAVA_HOME")
|
||||
if env:
|
||||
candidate = Path(env) / "bin" / _EXE
|
||||
if candidate.exists():
|
||||
return str(candidate)
|
||||
found = shutil.which("java")
|
||||
if found:
|
||||
return found
|
||||
for base in _COMMON_ROOTS:
|
||||
base_path = Path(base)
|
||||
if not base_path.is_dir():
|
||||
continue
|
||||
try:
|
||||
subdirs = sorted(base_path.iterdir(), key=_version_key, reverse=True)
|
||||
except OSError:
|
||||
continue # unreadable dir (permissions/AV) — not fatal, just try the next root
|
||||
for sub in subdirs:
|
||||
candidate = sub / "bin" / _EXE
|
||||
if candidate.exists():
|
||||
return str(candidate)
|
||||
# macOS JDK bundles nest an extra Contents/Home.
|
||||
mac_candidate = sub / "Contents" / "Home" / "bin" / _EXE
|
||||
if mac_candidate.exists():
|
||||
return str(mac_candidate)
|
||||
return None
|
||||
Reference in New Issue
Block a user