Add module that about java runtime management to core_lib.
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
import glob
|
||||
import logging
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from core_lib.common.exception import JavaRuntimeException, JavaRuntimeParseException
|
||||
|
||||
logger = logging.getLogger("Launcher.CoreLib")
|
||||
|
||||
def get_java_version(java_executable_path: str | Path) -> tuple[int, str]:
|
||||
if isinstance(java_executable_path, Path):
|
||||
java_executable_path = java_executable_path.as_posix()
|
||||
|
||||
try:
|
||||
process = subprocess.run(
|
||||
[java_executable_path, "-version"],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
timeout=10,
|
||||
)
|
||||
except subprocess.TimeoutExpired:
|
||||
raise JavaRuntimeException(
|
||||
"Java runtime timed out.",
|
||||
)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise JavaRuntimeException(
|
||||
"Unable to run Java runtime: {}".format(e.stderr),
|
||||
)
|
||||
except Exception as e:
|
||||
raise JavaRuntimeException(
|
||||
"An error occurred while executing Java runtime: {}".format(e),
|
||||
)
|
||||
|
||||
output = (process.stderr or "") + "\n" + (process.stdout or "")
|
||||
|
||||
match = re.search(r'version "([^"]+)"', output)
|
||||
if not match:
|
||||
raise JavaRuntimeParseException(
|
||||
f"Unable to parse Java version:\n{output}"
|
||||
)
|
||||
|
||||
raw_version = match.group(1)
|
||||
|
||||
if raw_version.startswith("1."):
|
||||
major = int(raw_version.split(".")[1])
|
||||
else:
|
||||
major = int(raw_version.split(".")[0])
|
||||
|
||||
return major, raw_version
|
||||
|
||||
def find_java_installations(extra_install_patterns: list | None=None) -> list[dict]:
|
||||
candidates_paths = []
|
||||
installations = []
|
||||
|
||||
java_executable_name = "java.exe" if sys.platform == "win32" else "java"
|
||||
|
||||
# Check (system) environment
|
||||
path_java = shutil.which("java")
|
||||
if path_java:
|
||||
candidates_paths.append(Path(path_java))
|
||||
|
||||
java_home = os.environ.get("JAVA_HOME")
|
||||
if java_home:
|
||||
candidates_paths.append(Path(java_home) / "bin" / java_executable_name)
|
||||
|
||||
system = platform.system().lower()
|
||||
|
||||
if system == "windows":
|
||||
patterns = [
|
||||
r"C:\Program Files\Java\*\bin\java.exe",
|
||||
r"C:\Program Files\Eclipse Adoptium\*\bin\java.exe",
|
||||
r"C:\Program Files\Microsoft\jdk-*\bin\java.exe",
|
||||
r"C:\Program Files (x86)\Java\*\bin\java.exe",
|
||||
]
|
||||
elif system == "darwin":
|
||||
patterns = [
|
||||
"/Library/Java/JavaVirtualMachines/*/Contents/Home/bin/java",
|
||||
"/System/Library/Java/JavaVirtualMachines/*/Contents/Home/bin/java",
|
||||
"/opt/homebrew/opt/openjdk*/bin/java",
|
||||
"/usr/local/opt/openjdk*/bin/java",
|
||||
"/Applications/*/Contents/jbr/Contents/Home/bin/java",
|
||||
]
|
||||
|
||||
else:
|
||||
patterns = [
|
||||
"/usr/bin/java",
|
||||
"/bin/java",
|
||||
"/usr/local/bin/java",
|
||||
"/usr/lib/jvm/*/bin/java",
|
||||
"/opt/java/*/bin/java",
|
||||
"/opt/jdk*/bin/java",
|
||||
"/snap/*/current/bin/java",
|
||||
]
|
||||
|
||||
if isinstance(extra_install_patterns, list):
|
||||
patterns.extend(extra_install_patterns)
|
||||
|
||||
for pattern in patterns:
|
||||
candidates_paths.extend(Path(p) for p in glob.glob(pattern))
|
||||
|
||||
seen = set()
|
||||
errors = []
|
||||
|
||||
for candidate_path in candidates_paths:
|
||||
try:
|
||||
converted_path = candidate_path.resolve().absolute()
|
||||
except OSError:
|
||||
continue
|
||||
|
||||
if converted_path in seen:
|
||||
continue
|
||||
|
||||
ver = None
|
||||
raw = None
|
||||
|
||||
try:
|
||||
ver, raw = get_java_version(converted_path)
|
||||
except JavaRuntimeParseException:
|
||||
|
||||
logger.debug(f"Unable to parse java version: {converted_path}")
|
||||
except JavaRuntimeException:
|
||||
logger.debug(f"Unable to run java executable: {converted_path}")
|
||||
except Exception as e:
|
||||
logger.exception(f"Unhandled exception: {e} (For path: {converted_path})")
|
||||
finally:
|
||||
if not ver:
|
||||
errors.append(converted_path)
|
||||
continue
|
||||
|
||||
logger.debug(f"Detected java version {ver} for path: {converted_path}")
|
||||
|
||||
installations.append(
|
||||
{
|
||||
"major": ver,
|
||||
"raw": raw,
|
||||
"homeDir": converted_path.parent.parent,
|
||||
"executable": converted_path,
|
||||
}
|
||||
)
|
||||
|
||||
installations.sort(key=lambda item: item["major"], reverse=True)
|
||||
|
||||
return installations
|
||||
Reference in New Issue
Block a user