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
47 changes: 30 additions & 17 deletions src/java/frameworks/java_cf_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package frameworks

import (
"fmt"
"github.com/cloudfoundry/java-buildpack/src/java/common"
"os"
"path/filepath"
"strings"

"github.com/cloudfoundry/java-buildpack/src/java/common"

"github.com/cloudfoundry/libbuildpack"
"gopkg.in/yaml.v2"
)
Expand All @@ -31,8 +32,8 @@ func (j *JavaCfEnvFramework) Detect() (string, error) {
return "", nil
}

// Check if Spring Boot 3.x is present
if !j.isSpringBoot3() {
// Check if Spring Boot 3.x/4.x is present
if !j.isSpringBootMajor(4) && !j.isSpringBootMajor(3) {
return "", nil
}

Expand All @@ -49,14 +50,27 @@ func (j *JavaCfEnvFramework) Detect() (string, error) {
func (j *JavaCfEnvFramework) Supply() error {
j.context.Log.BeginStep("Installing Java CF Env")

// Get java-cfenv dependency from manifest
dep, err := j.context.Manifest.DefaultVersion("java-cfenv")
dependency := "java-cfenv"
defaultVersion := "4.0.0"
versionPattern := "4.x.x"

if j.isSpringBootMajor(3) {
defaultVersion = "3.1.0"
versionPattern = "3.x.x"
}

allVersions := j.context.Manifest.AllDependencyVersions(dependency)
resolvedVersion, err := libbuildpack.FindMatchingVersion(versionPattern, allVersions)

dep := libbuildpack.Dependency{Name: dependency, Version: resolvedVersion}
if err != nil {
j.context.Log.Warning("Unable to determine Java CF Env version, using default")
j.context.Log.Warning("Unable to determine Java CF Env version for pattern %s, using default", versionPattern)
dep = libbuildpack.Dependency{
Name: "java-cfenv",
Version: "3.1.0", // Fallback version
Name: dependency,
Version: defaultVersion,
}
} else {
j.context.Log.Debug("Resolved Java CF Env version pattern '%s' to %s", versionPattern, resolvedVersion)
}

// Install java-cfenv JAR
Expand Down Expand Up @@ -139,15 +153,14 @@ func (j *JavaCfEnvFramework) isEnabled() bool {
return true
}

// isSpringBoot3 checks if the application is Spring Boot 3.x
func (j *JavaCfEnvFramework) isSpringBoot3() bool {
// Look for Spring Boot 3.x JARs
// Spring Boot 3.x uses spring-boot-3.*.jar
// isSpringBootMajor checks if the application is Spring Boot <major>.x
func (j *JavaCfEnvFramework) isSpringBootMajor(major int) bool {
jarGlob := fmt.Sprintf("spring-boot-%d.*.jar", major)
patterns := []string{
filepath.Join(j.context.Stager.BuildDir(), "**", "spring-boot-3.*.jar"),
filepath.Join(j.context.Stager.BuildDir(), "WEB-INF", "lib", "spring-boot-3.*.jar"),
filepath.Join(j.context.Stager.BuildDir(), "BOOT-INF", "lib", "spring-boot-3.*.jar"),
filepath.Join(j.context.Stager.BuildDir(), "lib", "spring-boot-3.*.jar"),
filepath.Join(j.context.Stager.BuildDir(), "**", jarGlob),
filepath.Join(j.context.Stager.BuildDir(), "WEB-INF", "lib", jarGlob),
filepath.Join(j.context.Stager.BuildDir(), "BOOT-INF", "lib", jarGlob),
filepath.Join(j.context.Stager.BuildDir(), "lib", jarGlob),
}

for _, pattern := range patterns {
Expand All @@ -161,7 +174,7 @@ func (j *JavaCfEnvFramework) isSpringBoot3() bool {
manifestPath := filepath.Join(j.context.Stager.BuildDir(), "META-INF", "MANIFEST.MF")
if content, err := os.ReadFile(manifestPath); err == nil {
manifest := string(content)
if strings.Contains(manifest, "Spring-Boot-Version: 3.") {
if strings.Contains(manifest, fmt.Sprintf("Spring-Boot-Version: %d.", major)) {
return true
}
}
Expand Down
36 changes: 31 additions & 5 deletions src/java/supply/supply_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package supply_test

import (
"github.com/cloudfoundry/java-buildpack/src/internal/mocks"
"github.com/golang/mock/gomock"
"os"
"path/filepath"
"time"

"github.com/cloudfoundry/java-buildpack/src/internal/mocks"
"github.com/golang/mock/gomock"

"github.com/cloudfoundry/java-buildpack/src/java/supply"
"github.com/cloudfoundry/libbuildpack"
. "github.com/onsi/ginkgo/v2"
Expand Down Expand Up @@ -177,7 +178,32 @@ dependencies: []
})
})

Context("When a Spring-boot application is present", func() {
Context("When a Spring-boot 4 application is present", func() {
BeforeEach(func() {
// Create a Spring Boot JAR with BOOT-INF
bootInfDir := filepath.Join(buildDir, "BOOT-INF")
Expect(os.MkdirAll(bootInfDir, 0755)).To(Succeed())
Expect(os.MkdirAll(filepath.Join(buildDir, "META-INF"), 0755)).To(Succeed())

// Create META-INF/MANIFEST.MF with corresponding content of a Spring Boot app
manifestFile := filepath.Join(buildDir, "META-INF", "MANIFEST.MF")
Expect(os.WriteFile(manifestFile, []byte("Spring-Boot-Version: 4.x.x"), 0644)).To(Succeed())

//Create install dir and mock for the java cf env spring boot related dependency
javaCfEnvInstallDir := filepath.Join(depsDir, depsIdx, "java_cf_env")
Expect(os.MkdirAll(filepath.Join(javaCfEnvInstallDir), 0755)).To(Succeed())

depJavaCfEnv := libbuildpack.Dependency{Name: "java-cfenv", Version: "4.999.0"}
mockManifest.EXPECT().AllDependencyVersions("java-cfenv").Return([]string{"4.999.0", "3.999.0"})
mockInstaller.EXPECT().InstallDependency(depJavaCfEnv, javaCfEnvInstallDir).Return(nil)
})

It("Supply passes successfully", func() {
Expect(supply.Run(supplier)).To(Succeed())
})
})

Context("When a Spring-boot 3 application is present", func() {
BeforeEach(func() {
// Create a Spring Boot JAR with BOOT-INF
bootInfDir := filepath.Join(buildDir, "BOOT-INF")
Expand All @@ -192,8 +218,8 @@ dependencies: []
javaCfEnvInstallDir := filepath.Join(depsDir, depsIdx, "java_cf_env")
Expect(os.MkdirAll(filepath.Join(javaCfEnvInstallDir), 0755)).To(Succeed())

depJavaCfEnv := libbuildpack.Dependency{Name: "java-cfenv", Version: "3.5.0"}
mockManifest.EXPECT().DefaultVersion("java-cfenv").Return(depJavaCfEnv, nil)
depJavaCfEnv := libbuildpack.Dependency{Name: "java-cfenv", Version: "3.999.0"}
mockManifest.EXPECT().AllDependencyVersions("java-cfenv").Return([]string{"4.999.0", "3.999.0"})
mockInstaller.EXPECT().InstallDependency(depJavaCfEnv, javaCfEnvInstallDir).Return(nil)
})

Expand Down