From e25829f3023fa721600b34f840f4e0449c626b06 Mon Sep 17 00:00:00 2001 From: Gayan Weerakutti Date: Fri, 18 Jul 2025 10:32:23 +0900 Subject: [PATCH 1/2] Handle error when java -version returns error While /usr/bin/java might exist on users macOS system, when no JDK or JRE is installed, it typically act as a placeholder or symlink meant to guide users toward installing Java. So in such case, when we call `java -version` it return an error instead of the version, which we need to handle. --- launchable/commands/verify.py | 18 ++++++++++++++---- tests/commands/test_verify.py | 10 +++++++++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/launchable/commands/verify.py b/launchable/commands/verify.py index 3af7e37f3..775ade891 100644 --- a/launchable/commands/verify.py +++ b/launchable/commands/verify.py @@ -3,6 +3,7 @@ import re import subprocess import sys +from subprocess import CalledProcessError from typing import List import click @@ -32,7 +33,10 @@ def pick(a, i): def compare_java_version(output: str) -> int: - """Check if the Java version meets what we need. returns >=0 if we meet the requirement""" + """ + Check if the Java version meets what we need. + Returns >=0 if we meet the requirement, or if we couldn't determine the version to be on the safe side + """ pattern = re.compile('"([^"]+)"') for l in output.splitlines(): if l.find("java version") != -1: @@ -49,9 +53,15 @@ def compare_java_version(output: str) -> int: def check_java_version(javacmd: str) -> int: - """Check if the Java version meets what we need. returns >=0 if we meet the requirement""" - v = subprocess.run([javacmd, "-version"], check=True, stderr=subprocess.PIPE, universal_newlines=True) - return compare_java_version(v.stderr) + """ + Check if the Java version meets what we need. + Returns >=0 if we meet the requirement, or if we couldn't determine the version to be on the safe side + """ + try: + v = subprocess.run([javacmd, "-version"], check=True, stderr=subprocess.PIPE, universal_newlines=True) + return compare_java_version(v.stderr) + except CalledProcessError: + return 0 @click.command(name="verify") diff --git a/tests/commands/test_verify.py b/tests/commands/test_verify.py index 50ffa16db..58a8acbd4 100644 --- a/tests/commands/test_verify.py +++ b/tests/commands/test_verify.py @@ -1,6 +1,8 @@ +from subprocess import CalledProcessError from unittest import TestCase +from unittest.mock import patch -from launchable.commands.verify import compare_java_version, compare_version +from launchable.commands.verify import check_java_version, compare_java_version, compare_version class VersionTest(TestCase): @@ -37,3 +39,9 @@ def test_java_version(self): Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_22-b03, mixed mode) """ ) < 0) + + @patch('launchable.commands.verify.subprocess.run') + def test_check_java_version(self, mock_run): + mock_run.side_effect = CalledProcessError(1, 'java -version') + result = check_java_version('java') + self.assertEqual(result, 0) From 8e79d16fb62f25805372f537b2f4314b3ab52119 Mon Sep 17 00:00:00 2001 From: Gayan Weerakutti Date: Fri, 18 Jul 2025 17:28:34 +0900 Subject: [PATCH 2/2] Refactor check_java_version to return -1 on command error Updated the check_java_version function to return -1. Even if the 'java' command exists, if the 'java -version' command returns non-zero value, we can safely assume that java is not installed. --- launchable/commands/verify.py | 10 ++++------ tests/commands/test_verify.py | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/launchable/commands/verify.py b/launchable/commands/verify.py index 775ade891..7fcc1e69c 100644 --- a/launchable/commands/verify.py +++ b/launchable/commands/verify.py @@ -33,10 +33,7 @@ def pick(a, i): def compare_java_version(output: str) -> int: - """ - Check if the Java version meets what we need. - Returns >=0 if we meet the requirement, or if we couldn't determine the version to be on the safe side - """ + """Check if the Java version meets what we need. returns >=0 if we meet the requirement""" pattern = re.compile('"([^"]+)"') for l in output.splitlines(): if l.find("java version") != -1: @@ -55,13 +52,14 @@ def compare_java_version(output: str) -> int: def check_java_version(javacmd: str) -> int: """ Check if the Java version meets what we need. - Returns >=0 if we meet the requirement, or if we couldn't determine the version to be on the safe side + Returns >=0 if we meet the requirement + Returns -1 if 'java -version' command returns non-zero exit status """ try: v = subprocess.run([javacmd, "-version"], check=True, stderr=subprocess.PIPE, universal_newlines=True) return compare_java_version(v.stderr) except CalledProcessError: - return 0 + return -1 @click.command(name="verify") diff --git a/tests/commands/test_verify.py b/tests/commands/test_verify.py index 58a8acbd4..879cee51c 100644 --- a/tests/commands/test_verify.py +++ b/tests/commands/test_verify.py @@ -44,4 +44,4 @@ def test_java_version(self): def test_check_java_version(self, mock_run): mock_run.side_effect = CalledProcessError(1, 'java -version') result = check_java_version('java') - self.assertEqual(result, 0) + self.assertEqual(result, -1)