Skip to content

Commit 1b128e4

Browse files
authored
Merge pull request #1226 from zakerf/spring-boot-4-support
add support for spring boot 4, with a fallback to 3
2 parents 32198a4 + 779c8af commit 1b128e4

2 files changed

Lines changed: 64 additions & 23 deletions

File tree

src/java/frameworks/java_cf_env.go

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ package frameworks
22

33
import (
44
"fmt"
5-
"github.com/cloudfoundry/java-buildpack/src/java/common"
65
"os"
76
"path/filepath"
87
"strings"
98

9+
"github.com/cloudfoundry/java-buildpack/src/java/common"
10+
1011
"github.com/cloudfoundry/libbuildpack"
1112
)
1213

@@ -30,14 +31,14 @@ func (j *JavaCfEnvFramework) Detect() (string, error) {
3031
return "", nil
3132
}
3233

33-
// Check if Spring Boot 3.x is present
34-
if !j.isSpringBoot3() {
34+
// Check if Spring Boot 3.x/4.x is present
35+
if !j.isSpringBootMajor(4) && !j.isSpringBootMajor(3) {
3536
return "", nil
3637
}
3738

3839
// Don't enable if java-cfenv is already in the application
3940
if j.hasJavaCfEnv() {
40-
j.context.Log.Debug("java-cfenv already present in application")
41+
j.context.Log.Info("java-cfenv already present in application")
4142
return "", nil
4243
}
4344

@@ -48,14 +49,27 @@ func (j *JavaCfEnvFramework) Detect() (string, error) {
4849
func (j *JavaCfEnvFramework) Supply() error {
4950
j.context.Log.Debug("Installing Java CF Env")
5051

51-
// Get java-cfenv dependency from manifest
52-
dep, err := j.context.Manifest.DefaultVersion("java-cfenv")
52+
dependency := "java-cfenv"
53+
defaultVersion := "4.0.0"
54+
versionPattern := "4.x.x"
55+
56+
if j.isSpringBootMajor(3) {
57+
defaultVersion = "3.5.1"
58+
versionPattern = "3.x.x"
59+
}
60+
61+
allVersions := j.context.Manifest.AllDependencyVersions(dependency)
62+
resolvedVersion, err := libbuildpack.FindMatchingVersion(versionPattern, allVersions)
63+
64+
dep := libbuildpack.Dependency{Name: dependency, Version: resolvedVersion}
5365
if err != nil {
54-
j.context.Log.Warning("Unable to determine Java CF Env version, using default")
66+
j.context.Log.Warning("Unable to determine Java CF Env version for pattern %s, using default", versionPattern)
5567
dep = libbuildpack.Dependency{
56-
Name: "java-cfenv",
57-
Version: "3.1.0", // Fallback version
68+
Name: dependency,
69+
Version: defaultVersion,
5870
}
71+
} else {
72+
j.context.Log.Debug("Resolved Java CF Env version pattern '%s' to %s", versionPattern, resolvedVersion)
5973
}
6074

6175
// Install java-cfenv JAR
@@ -139,15 +153,14 @@ func (j *JavaCfEnvFramework) isEnabled() bool {
139153
return true
140154
}
141155

142-
// isSpringBoot3 checks if the application is Spring Boot 3.x
143-
func (j *JavaCfEnvFramework) isSpringBoot3() bool {
144-
// Look for Spring Boot 3.x JARs
145-
// Spring Boot 3.x uses spring-boot-3.*.jar
156+
// isSpringBootMajor checks if the application is Spring Boot <major>.x
157+
func (j *JavaCfEnvFramework) isSpringBootMajor(major int) bool {
158+
jarGlob := fmt.Sprintf("spring-boot-%d.*.jar", major)
146159
patterns := []string{
147-
filepath.Join(j.context.Stager.BuildDir(), "**", "spring-boot-3.*.jar"),
148-
filepath.Join(j.context.Stager.BuildDir(), "WEB-INF", "lib", "spring-boot-3.*.jar"),
149-
filepath.Join(j.context.Stager.BuildDir(), "BOOT-INF", "lib", "spring-boot-3.*.jar"),
150-
filepath.Join(j.context.Stager.BuildDir(), "lib", "spring-boot-3.*.jar"),
160+
filepath.Join(j.context.Stager.BuildDir(), "**", jarGlob),
161+
filepath.Join(j.context.Stager.BuildDir(), "WEB-INF", "lib", jarGlob),
162+
filepath.Join(j.context.Stager.BuildDir(), "BOOT-INF", "lib", jarGlob),
163+
filepath.Join(j.context.Stager.BuildDir(), "lib", jarGlob),
151164
}
152165

153166
for _, pattern := range patterns {
@@ -161,7 +174,7 @@ func (j *JavaCfEnvFramework) isSpringBoot3() bool {
161174
manifestPath := filepath.Join(j.context.Stager.BuildDir(), "META-INF", "MANIFEST.MF")
162175
if content, err := os.ReadFile(manifestPath); err == nil {
163176
manifest := string(content)
164-
if strings.Contains(manifest, "Spring-Boot-Version: 3.") {
177+
if strings.Contains(manifest, fmt.Sprintf("Spring-Boot-Version: %d.", major)) {
165178
return true
166179
}
167180
}

src/java/supply/supply_test.go

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package supply_test
22

33
import (
4-
"github.com/cloudfoundry/java-buildpack/src/internal/mocks"
5-
"github.com/golang/mock/gomock"
64
"os"
75
"path/filepath"
86
"time"
97

8+
"github.com/cloudfoundry/java-buildpack/src/internal/mocks"
9+
"github.com/golang/mock/gomock"
10+
1011
"github.com/cloudfoundry/java-buildpack/src/java/supply"
1112
"github.com/cloudfoundry/libbuildpack"
1213
. "github.com/onsi/ginkgo/v2"
@@ -177,7 +178,33 @@ dependencies: []
177178
})
178179
})
179180

180-
Context("When a Spring-boot application is present", func() {
181+
Context("When a Spring-boot 4 application is present", func() {
182+
BeforeEach(func() {
183+
// Create a Spring Boot JAR with BOOT-INF
184+
bootInfDir := filepath.Join(buildDir, "BOOT-INF")
185+
Expect(os.MkdirAll(bootInfDir, 0755)).To(Succeed())
186+
Expect(os.MkdirAll(filepath.Join(buildDir, "META-INF"), 0755)).To(Succeed())
187+
188+
// Create META-INF/MANIFEST.MF with corresponding content of a Spring Boot app
189+
manifestFile := filepath.Join(buildDir, "META-INF", "MANIFEST.MF")
190+
Expect(os.WriteFile(manifestFile, []byte("Spring-Boot-Version: 4.x.x"), 0644)).To(Succeed())
191+
192+
//Create install dir and mock for the java cf env spring boot related dependency
193+
javaCfEnvInstallDir := filepath.Join(depsDir, depsIdx, "java_cf_env")
194+
Expect(os.MkdirAll(filepath.Join(javaCfEnvInstallDir), 0755)).To(Succeed())
195+
196+
depJavaCfEnv := libbuildpack.Dependency{Name: "java-cfenv", Version: "4.999.0"}
197+
mockManifest.EXPECT().DefaultVersion("java-cfenv").Return(depJavaCfEnv, nil)
198+
mockManifest.EXPECT().AllDependencyVersions("java-cfenv").Return([]string{"4.999.0", "3.999.0"})
199+
mockInstaller.EXPECT().InstallDependency(depJavaCfEnv, javaCfEnvInstallDir).Return(nil)
200+
})
201+
202+
It("Supply passes successfully", func() {
203+
Expect(supply.Run(supplier)).To(Succeed())
204+
})
205+
})
206+
207+
Context("When a Spring-boot 3 application is present", func() {
181208
BeforeEach(func() {
182209
// Create a Spring Boot JAR with BOOT-INF
183210
bootInfDir := filepath.Join(buildDir, "BOOT-INF")
@@ -192,8 +219,9 @@ dependencies: []
192219
javaCfEnvInstallDir := filepath.Join(depsDir, depsIdx, "java_cf_env")
193220
Expect(os.MkdirAll(filepath.Join(javaCfEnvInstallDir), 0755)).To(Succeed())
194221

195-
depJavaCfEnv := libbuildpack.Dependency{Name: "java-cfenv", Version: "3.5.0"}
196-
mockManifest.EXPECT().DefaultVersion("java-cfenv").Return(depJavaCfEnv, nil).Times(2)
222+
depJavaCfEnv := libbuildpack.Dependency{Name: "java-cfenv", Version: "3.999.0"}
223+
mockManifest.EXPECT().DefaultVersion("java-cfenv").Return(depJavaCfEnv, nil)
224+
mockManifest.EXPECT().AllDependencyVersions("java-cfenv").Return([]string{"4.999.0", "3.999.0"})
197225
mockInstaller.EXPECT().InstallDependency(depJavaCfEnv, javaCfEnvInstallDir).Return(nil)
198226
})
199227

0 commit comments

Comments
 (0)