Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 23 additions & 20 deletions src/java/jres/jre.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ type BaseComponent struct {
// DetectJREByEnv checks environment variables for JRE selection
// Takes the internal JRE name (e.g., "sapmachine", "openjdk", "zulu")
// Checks both auto-generated and documented environment variable names
// This matches the behavior of GetJREVersion and the Ruby buildpack
// This matches the behavior of GetJREVersion
func DetectJREByEnv(jreName string) bool {
// Check auto-generated name pattern (e.g., JBP_CONFIG_SAPMACHINE)
envKey := fmt.Sprintf("JBP_CONFIG_%s", strings.ToUpper(strings.ReplaceAll(jreName, "-", "_")))
Expand Down Expand Up @@ -275,27 +275,30 @@ func GetJREVersion(ctx *common.Context, jreName string) (libbuildpack.Dependency

versionPattern := parseJBPConfigVersion(envVal)
if versionPattern == "" {
return libbuildpack.Dependency{}, fmt.Errorf("could not parse version from %s='%s'", envKey, envVal)
}
ctx.Log.Debug("Parsed version pattern from %s: '%s'", envKey, versionPattern)

normalizedPattern := normalizeVersionPattern(versionPattern)
ctx.Log.Debug("Normalized pattern: '%s' -> '%s'", versionPattern, normalizedPattern)
// No version specified — env var is used for other settings (e.g. memory_calculator).
// Fall back to manifest default.
ctx.Log.Debug("%s set but contains no version field, using manifest default", envKey)
} else {
ctx.Log.Debug("Parsed version pattern from %s: '%s'", envKey, versionPattern)

normalizedPattern := normalizeVersionPattern(versionPattern)
ctx.Log.Debug("Normalized pattern: '%s' -> '%s'", versionPattern, normalizedPattern)

availableVersions := ctx.Manifest.AllDependencyVersions(jreName)
if len(availableVersions) == 0 {
return libbuildpack.Dependency{}, fmt.Errorf("no versions of %s found in manifest", jreName)
}
ctx.Log.Debug("Available versions for %s: %v", jreName, availableVersions)

availableVersions := ctx.Manifest.AllDependencyVersions(jreName)
if len(availableVersions) == 0 {
return libbuildpack.Dependency{}, fmt.Errorf("no versions of %s found in manifest", jreName)
}
ctx.Log.Debug("Available versions for %s: %v", jreName, availableVersions)
matchedVersion, err := libbuildpack.FindMatchingVersion(normalizedPattern, availableVersions)
if err != nil {
ctx.Log.Debug("FindMatchingVersion failed: %s", err.Error())
return libbuildpack.Dependency{}, fmt.Errorf("no version of %s matching '%s' found in manifest. Available versions: %v", jreName, versionPattern, availableVersions)
}
ctx.Log.Debug("Matched version: %s", matchedVersion)

matchedVersion, err := libbuildpack.FindMatchingVersion(normalizedPattern, availableVersions)
if err != nil {
ctx.Log.Debug("FindMatchingVersion failed: %s", err.Error())
return libbuildpack.Dependency{}, fmt.Errorf("no version of %s matching '%s' found in manifest. Available versions: %v", jreName, versionPattern, availableVersions)
return libbuildpack.Dependency{Name: jreName, Version: matchedVersion}, nil
}
ctx.Log.Debug("Matched version: %s", matchedVersion)

return libbuildpack.Dependency{Name: jreName, Version: matchedVersion}, nil
}

// Get default version from manifest (no version constraint)
Expand Down Expand Up @@ -397,7 +400,7 @@ func WriteJavaHomeProfileD(ctx *common.Context, jreDir, javaHome string) error {
}

// Create the profile.d script content with JAVA_HOME, JRE_HOME, and PATH
// Following the pattern from reference buildpacks (Ruby, Python, Go)
// Create the profile.d script content with JAVA_HOME, JRE_HOME, and PATH
envContent := fmt.Sprintf(`export JAVA_HOME=%s
export JRE_HOME=%s
export PATH=$JAVA_HOME/bin:$PATH
Expand Down
21 changes: 16 additions & 5 deletions src/java/jres/jre_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,11 +344,11 @@ dependencies:
Expect(err.Error()).To(ContainSubstring("no version of openjdk matching"))
})

It("fails when config format is invalid", func() {
It("falls back to default version when config format has no version", func() {
os.Setenv("JBP_CONFIG_OPENJDK", "invalid config")
_, err := jres.GetJREVersion(ctx, "openjdk")
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("could not parse version"))
dep, err := jres.GetJREVersion(ctx, "openjdk")
Expect(err).NotTo(HaveOccurred())
Expect(dep.Version).NotTo(BeEmpty())
})
})

Expand Down Expand Up @@ -394,6 +394,17 @@ dependencies:
Expect(err).NotTo(HaveOccurred())
Expect(dep.Version).To(Equal("21.0.5"))
})

// https://github.com/cloudfoundry/java-buildpack/issues/1270
// JBP_CONFIG_OPEN_JDK_JRE with only memory_calculator settings (no version)
// should fall back to manifest default, not fail.
It("falls back to default version when only memory_calculator is set", func() {
os.Setenv("JBP_CONFIG_OPEN_JDK_JRE", "{ memory_calculator: { class_count: 30000 } }")
dep, err := jres.GetJREVersion(ctx, "openjdk")
Expect(err).NotTo(HaveOccurred())
Expect(dep.Name).To(Equal("openjdk"))
Expect(dep.Version).NotTo(BeEmpty())
})
})

Context("documented environment variables for all JREs", func() {
Expand Down Expand Up @@ -592,7 +603,7 @@ IMPLEMENTOR="Eclipse Adoptium"`
})
})

Describe("JRE Detection with Environment Variables (Ruby buildpack compatibility)", func() {
Describe("JRE Detection with Environment Variables", func() {
var testLogBuffer *bytes.Buffer
var testCtx *common.Context

Expand Down