diff --git a/manifest.yml b/manifest.yml index e1492243a..bd28ce9fb 100644 --- a/manifest.yml +++ b/manifest.yml @@ -39,6 +39,8 @@ default_versions: - name: auto-reconfiguration version: 2.x - name: java-cfenv + version: 4.x +- name: java-cfenv-sb3 version: 3.x - name: client-certificate-mapper version: 2.x @@ -283,7 +285,7 @@ dependencies: - cflinuxfs4 source: https://repo1.maven.org/maven2/org/jacoco/jacoco/0.8.14/jacoco-0.8.14.zip source_sha256: 0372447f54900b4e77bcb216985b7d31cf5318fc599f8f9346ee35830448c125 -- name: java-cfenv +- name: java-cfenv-sb3 version: 3.5.0 uri: https://java-buildpack.cloudfoundry.org/java-cfenv/java-cfenv-3.5.0.jar sha256: 6a761fe530783c0ec9e6d1713ef54f6504803bf1ad02856d3ee7b46211f905c5 @@ -291,6 +293,14 @@ dependencies: - cflinuxfs4 source: https://repo1.maven.org/maven2/io/pivotal/cfenv/java-cfenv/3.5.0/java-cfenv-3.5.0.jar source_sha256: 9cc8d4c368bc90eafb7b6b14bc34c57ef5523f3ec8546e3fbd91326cdfc13500 +- name: java-cfenv + version: 4.0.0 + uri: https://java-buildpack.cloudfoundry.org/java-cfenv/java-cfenv-4.0.0.jar + sha256: caa4a78642a39df4fe01ed2013fef1f58ac7ce5376d7791f9b4c8f6eba9da94e + cf_stacks: + - cflinuxfs4 + source: https://repo1.maven.org/maven2/io/pivotal/cfenv/java-cfenv/4.0.0/java-cfenv-4.0.0.jar + source_sha256: caa4a78642a39df4fe01ed2013fef1f58ac7ce5376d7791f9b4c8f6eba9da94e - name: java-memory-assistant version: 0.5.0 uri: https://github.com/SAP/java-memory-assistant/releases/download/0.5.0/java-memory-assistant-0.5.0.jar diff --git a/src/java/frameworks/java_cf_env.go b/src/java/frameworks/java_cf_env.go index f1a0294ef..ba0aabe81 100644 --- a/src/java/frameworks/java_cf_env.go +++ b/src/java/frameworks/java_cf_env.go @@ -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" ) @@ -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 } @@ -49,13 +50,21 @@ func (j *JavaCfEnvFramework) Detect() (string, error) { func (j *JavaCfEnvFramework) Supply() error { j.context.Log.BeginStep("Installing Java CF Env") + dependency := "java-cfenv" + defaultVersion := "4.0.0" + + if j.isSpringBootMajor(3) { + dependency = "java-cfenv-sb3" + defaultVersion = "3.1.0" + } + // Get java-cfenv dependency from manifest - dep, err := j.context.Manifest.DefaultVersion("java-cfenv") + dep, err := j.context.Manifest.DefaultVersion(dependency) if err != nil { j.context.Log.Warning("Unable to determine Java CF Env version, using default") dep = libbuildpack.Dependency{ - Name: "java-cfenv", - Version: "3.1.0", // Fallback version + Name: dependency, + Version: defaultVersion, } } @@ -139,15 +148,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 .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 { @@ -161,7 +169,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 } } diff --git a/src/java/supply/supply_test.go b/src/java/supply/supply_test.go index 18a6086e2..7a5603dd2 100644 --- a/src/java/supply/supply_test.go +++ b/src/java/supply/supply_test.go @@ -177,7 +177,7 @@ 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") @@ -186,13 +186,13 @@ dependencies: [] // 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: 3.x.x"), 0644)).To(Succeed()) + 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: "3.5.0"} + depJavaCfEnv := libbuildpack.Dependency{Name: "java-cfenv", Version: "4.0.0"} mockManifest.EXPECT().DefaultVersion("java-cfenv").Return(depJavaCfEnv, nil) mockInstaller.EXPECT().InstallDependency(depJavaCfEnv, javaCfEnvInstallDir).Return(nil) }) @@ -202,6 +202,31 @@ dependencies: [] }) }) + 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") + 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: 3.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-sb3", Version: "3.5.0"} + mockManifest.EXPECT().DefaultVersion("java-cfenv-sb3").Return(depJavaCfEnv, nil) + mockInstaller.EXPECT().InstallDependency(depJavaCfEnv, javaCfEnvInstallDir).Return(nil) + }) + + It("Supply passes successfully", func() { + Expect(supply.Run(supplier)).To(Succeed()) + }) + }) + Context("When a Groovy application is present", func() { BeforeEach(func() { // Create a .groovy file