Skip to content

Add support for 4 digit sapmachine versions - #1443

Open
kiril-keranov wants to merge 2 commits into
cloudfoundry:mainfrom
kiril-keranov:support_4digit_sapmachine_versions
Open

kiril-keranov wants to merge 2 commits into
cloudfoundry:mainfrom
kiril-keranov:support_4digit_sapmachine_versions

Conversation

@kiril-keranov

Copy link
Copy Markdown
Contributor

Summary

SapMachine occasionally releases patch versions using a 4-part version scheme (e.g. 17.0.0.1). The buildpack previously had no support for this format — specifying a 4-digit version would cause the semver matching libraries to fail, since neither blang/semver nor Masterminds/semver can parse 4-part version strings.

Changes

  • src/java/jres/jre.go: Add exactVersion4PartRegex and isValidVersion4Part() to identify X.Y.Z.W strings. Add findVersion() helper that performs direct string matching for exact 4-digit versions, and filters 4-digit entries out of the semver candidate list for range patterns (e.g. 17.+) to prevent parse failures. Update normalizeVersionPattern() to treat 4-digit versions as fully specified and not append .*. Replace all libbuildpack.FindMatchingVersion calls in GetJREVersion with findVersion.
  • manifest.yml: Update the url_to_dependency_map regex for sapmachine from (\d+\.\d+\.\d+) to (\d+\.\d+\.\d+(?:\.\d+)?) so 4-digit filenames like sapmachine-jre-17.0.0.1_linux-x64_bin.tar.gz are correctly mapped.
  • src/java/jres/jre_test.go: Add a 17.0.17.1 entry to the test fixture manifest and two new test cases covering exact 4-digit resolution via BP_JAVA_VERSION and JBP_CONFIG_SAP_MACHINE_JRE.

Test plan

  • BP_JAVA_VERSION=17.0.0.1 resolves to the exact 4-digit sapmachine version
  • JBP_CONFIG_SAP_MACHINE_JRE={jre: {version: 17.0.0.1}} resolves to the exact 4-digit version
  • JBP_CONFIG_SAP_MACHINE_JRE={jre: {version: 17.+}} with mixed 3- and 4-digit versions in the manifest resolves to the highest 3-digit match, unaffected by 4-digit entries
  • All existing JREs (OpenJDK, Zulu, IBM, Oracle, GraalVM, Zing) continue to resolve versions correctly — `go test ./src/java/jres/...

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Mixed-version manifests still break default resolution and installation of three-part SapMachine versions.

Review effort: Balanced
Findings: 1 High severity

Open (1)
What changed in this PR

Extends the Java buildpack’s JRE resolver to recognize exact four-part SapMachine versions.

Changes:

  • Adds exact four-part matching and excludes four-part candidates from semver lookups.
  • Updates SapMachine URL mapping to capture an optional fourth component.
  • Adds resolution tests for both supported environment-variable formats.
File Description
src/​java/​jres/​jre.go Adds four-part version recognition and matching.
src/​java/​jres/​jre_test.go Adds a mixed-version fixture and exact-resolution tests.
manifest.yml Captures four-part SapMachine versions from URLs.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/java/jres/jre.go Outdated
Comment on lines +334 to +335
if !isValidVersion4Part(v) {
semverVersions = append(semverVersions, v)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with this finding. Before extending findVersion's 4-part handling to Manifest.DefaultVersion and Installer.InstallDependency's warnNewerPatch, it'd help to first add a failing regression test that reproduces it — e.g. a manifest fixture mixing a 4-part sapmachine version with the current default line, no BP_JAVA_VERSION/JBP_CONFIG_* set, asserting GetJREVersion (or the install step) currently errors/panics on the unfiltered semver parse. That pins down the exact failure mode and guards the fix from regressing once applied.

@kiril-keranov kiril-keranov Oct 6, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, @stokpop I've addressed this with 170f82f. There are also regression tests included in jre_test , can you please check? I've run the integration tests on the modifications and they passed well

@stokpop stokpop left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some changes/checks requested in comments

@stokpop
stokpop self-requested a review October 6, 2026 12:12

@stokpop stokpop left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding the regression tests for DefaultVersion and warnNewerPatch. Requesting changes for one functional issue (install of an exact 4-part version fails, see inline comment on jre.go). The comment on the CLI entry points is a design point to consider, not blocking.

Minor: the PR description still mentions findVersion and filtering in normalizeVersionPattern. Those were replaced by Extract4PartEntries and Manifest4Part. Could you update it?

Comment thread src/java/jres/jre.go
// through the normal semver matching path.
func resolveVersion(ctx *common.Context, jreName, version string) (libbuildpack.Dependency, error) {
if isValidVersion4Part(version) {
if entry, ok := ctx.Manifest4Part[version]; ok && entry.Dependency.Name == jreName {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An exact 4-part version now resolves, but it can't be installed. Extract4PartEntries removes the entry from manifest.ManifestEntries. BaseJRE.Supply then calls Installer.InstallDependency, which looks the dependency up again through manifest.GetEntry and fails:

dependency sapmachine 17.0.17.1 not found

The current tests only call GetJREVersion, so this isn't caught. The integration tests don't hit it either, because manifest.yml has no 4-part SapMachine entry.

Could you add a test that runs the real libbuildpack.Installer.InstallDependency for 17.0.17.1 after extraction? Use a fixture entry pointing at a local file:// tarball with a matching sha256. Then make install work for 4-part entries.

// Extract 4-part sapmachine versions before libbuildpack sees the manifest.
// Neither blang/semver nor Masterminds/semver can parse X.Y.Z.W strings;
// leaving them in the manifest breaks DefaultVersion and warnNewerPatch.
manifest4Part := jres.Extract4PartEntries(manifest, "sapmachine")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To consider, now or in a follow-up (same applies to finalize/cli/main.go)

Not blocking. 4-part versions come from a libbuildpack semver limitation, not from SapMachine itself; other vendors such as Corretto use them too. Long term it would be nice not to hardcode "sapmachine" in the CLI entry points.

Options, either in this PR or later:

  • Minimal: drop the dependency-name filter so all 4-part entries are extracted. There are no 4-part versions in manifest.yml today, so this changes nothing now. The catch is that only the JRE path reads Manifest4Part. A future 4-part entry for a non-JRE dependency would disappear from DefaultVersion without a clear error.
  • Generic: common.Manifest and common.Installer are already interfaces. A decorator would keep 4-part handling in one place: hide 4-part entries from the semver paths and serve exact 4-part lookups and installs directly. It would also remove the Context.Manifest4Part field and the variadic NewFinalizer(..., manifest4Part ...) parameter. It may also be the simplest way to fix the install issue above.

Fine with a SapMachine-only special case for now if the install issue is fixed. Happy to track the generic approach as a follow-up issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants