From 66978263a34f6d43f158a6fa74a6c4fedde4a8bb Mon Sep 17 00:00:00 2001 From: Jeff Lenamon <85593689+lenamonj@users.noreply.github.com> Date: Sun, 6 Sep 2026 16:32:26 -0400 Subject: [PATCH] fix: use the JDK version from the JAR when no language version is recorded The expression jdk_from_jar or existing if existing else "8" parses as (jdk_from_jar or existing) if existing else "8", so with no recorded language version the JDK version read from the Maven Central JAR was discarded and the spec defaulted to 8. The order is now JAR, then the existing value, then the default, as the comment above it describes. Closes #1464 Signed-off-by: Jeff Lenamon --- .../common_spec/maven_spec.py | 2 +- .../common_spec/test_maven_spec.py | 66 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 tests/build_spec_generator/common_spec/test_maven_spec.py diff --git a/src/macaron/build_spec_generator/common_spec/maven_spec.py b/src/macaron/build_spec_generator/common_spec/maven_spec.py index 7f20ce741..cb5bd6c24 100644 --- a/src/macaron/build_spec_generator/common_spec/maven_spec.py +++ b/src/macaron/build_spec_generator/common_spec/maven_spec.py @@ -84,7 +84,7 @@ def resolve_fields(self, purl: PackageURL) -> None: existing = self.data["language_version"][0] if self.data["language_version"] else None # Select JDK from jar or another source, with a default of version 8. - selected_jdk_version = jdk_from_jar or existing if existing else "8" + selected_jdk_version = jdk_from_jar or existing or "8" major_jdk_version = normalize_jdk_version(selected_jdk_version) if not major_jdk_version: diff --git a/tests/build_spec_generator/common_spec/test_maven_spec.py b/tests/build_spec_generator/common_spec/test_maven_spec.py new file mode 100644 index 000000000..670419755 --- /dev/null +++ b/tests/build_spec_generator/common_spec/test_maven_spec.py @@ -0,0 +1,66 @@ +# Copyright (c) 2026 - 2026, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/. + +"""This module tests the Maven build specification field resolution.""" + +from unittest.mock import patch + +import pytest +from packageurl import PackageURL + +from macaron.build_spec_generator.common_spec.base_spec import BaseBuildSpecDict +from macaron.build_spec_generator.common_spec.maven_spec import MavenBuildSpec + +PURL_STRING = "pkg:maven/com.example/demo@1.0.0" + + +def _build_spec_dict(language_version: list[str]) -> BaseBuildSpecDict: + """Return a minimal Maven build spec dict carrying the passed language version list.""" + return BaseBuildSpecDict( + ecosystem="maven", + purl=PURL_STRING, + language="java", + build_tools=["maven"], + macaron_version="0.0.0", + group_id="com.example", + artifact_id="demo", + version="1.0.0", + language_version=list(language_version), + build_commands=[ + { + "build_tool": "maven", + "build_config_path": "pom.xml", + "command": ["mvn", "clean", "package"], + "confidence_score": 1.0, + } + ], + ) + + +def _resolve(language_version: list[str], jdk_from_jar: str | None) -> list[str]: + """Resolve a Maven build spec with the JAR lookup pinned, and return the resulting language version.""" + data = _build_spec_dict(language_version) + with patch( + "macaron.build_spec_generator.common_spec.maven_spec.find_jdk_version_from_central_maven_repo", + return_value=jdk_from_jar, + ): + MavenBuildSpec(data).resolve_fields(PackageURL.from_string(PURL_STRING)) + return data["language_version"] + + +@pytest.mark.parametrize( + ("existing", "jdk_from_jar", "expected"), + [ + # The JAR manifest is the strongest evidence and wins whether or not the database + # recorded a language version. The empty-list case is the ordinary one: core.py sets + # "language_version" to [] whenever the database holds no recorded version. + ([], "17", ["17"]), + (["11"], "17", ["17"]), + # No JAR evidence: fall back to what the database recorded, then to the default of 8. + (["11"], None, ["11"]), + ([], None, ["8"]), + ], +) +def test_resolve_fields_selects_jdk_version(existing: list[str], jdk_from_jar: str | None, expected: list[str]) -> None: + """The JDK read from the Maven Central JAR must not be discarded when the database recorded none.""" + assert _resolve(existing, jdk_from_jar) == expected