Skip to content

Commit 54a1476

Browse files
fix: reject JDK < 11 early with clear error message
When running with JDK 8, the pipeline would fail late with a cryptic UnsupportedClassVersionError from the runtime JAR. Now checks the detected Java version in ensure_runtime_environment() and returns False with a clear error message explaining that JDK 11+ is required. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 5ee642e commit 54a1476

2 files changed

Lines changed: 56 additions & 0 deletions

File tree

codeflash/languages/java/support.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,21 @@ def ensure_runtime_environment(self, project_root: Path) -> bool:
546546
if self._language_version is None:
547547
self._detect_java_version()
548548

549+
if self._language_version is not None:
550+
try:
551+
major = int(self._language_version)
552+
if major < 11:
553+
logger.error(
554+
"Java %s detected, but codeflash requires JDK 11 or later. "
555+
"The codeflash-runtime JAR and --add-opens flags are incompatible with JDK %s. "
556+
"Please install JDK 11+ and ensure it is on your PATH.",
557+
self._language_version,
558+
self._language_version,
559+
)
560+
return False
561+
except ValueError:
562+
pass
563+
549564
self._test_framework = config.test_framework
550565

551566
return True

tests/test_languages/test_java/test_support.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,44 @@ def test_discover_functions_from_fixture(self, support, java_fixture_path: Path)
134134
source = calculator_file.read_text(encoding="utf-8")
135135
functions = support.discover_functions(source, calculator_file)
136136
assert len(functions) > 0
137+
138+
139+
class TestJdkVersionCheck:
140+
def test_jdk8_rejected(self, tmp_path: Path) -> None:
141+
from unittest.mock import MagicMock, patch
142+
143+
support = get_java_support()
144+
145+
mock_config = MagicMock()
146+
mock_config.java_version = "8"
147+
mock_config.test_framework = "junit5"
148+
149+
with patch("codeflash.languages.java.support.detect_java_project", return_value=mock_config):
150+
result = support.ensure_runtime_environment(tmp_path)
151+
assert result is False
152+
153+
def test_jdk11_accepted(self, tmp_path: Path) -> None:
154+
from unittest.mock import MagicMock, patch
155+
156+
support = get_java_support()
157+
158+
mock_config = MagicMock()
159+
mock_config.java_version = "11"
160+
mock_config.test_framework = "junit5"
161+
162+
with patch("codeflash.languages.java.support.detect_java_project", return_value=mock_config):
163+
result = support.ensure_runtime_environment(tmp_path)
164+
assert result is True
165+
166+
def test_jdk21_accepted(self, tmp_path: Path) -> None:
167+
from unittest.mock import MagicMock, patch
168+
169+
support = get_java_support()
170+
171+
mock_config = MagicMock()
172+
mock_config.java_version = "21"
173+
mock_config.test_framework = "junit5"
174+
175+
with patch("codeflash.languages.java.support.detect_java_project", return_value=mock_config):
176+
result = support.ensure_runtime_environment(tmp_path)
177+
assert result is True

0 commit comments

Comments
 (0)