diff --git a/docs/framework-java-cfenv.md b/docs/framework-java-cfenv.md index e9bbb31c71..819967f55b 100644 --- a/docs/framework-java-cfenv.md +++ b/docs/framework-java-cfenv.md @@ -1,15 +1,22 @@ # Java CfEnv Framework -The Java CfEnv Framework provides the `java-cfenv` library for Spring Boot 3+ applications. This library sets various Spring Boot properties by parsing CloudFoundry variables such as `VCAP_SERVICES`, allowing Spring Boot's autoconfiguration to kick in. +The Java CfEnv Framework provides the `java-cfenv` library for Spring Boot 3.x and 4.x applications. This library sets various Spring Boot properties by parsing Cloud Foundry variables such as `VCAP_SERVICES`, allowing Spring Boot's autoconfiguration to kick in. -This is the recommended replacement for Spring AutoReconfiguration library which is deprecated. See the `java-cfenv` repostitory for more detail. +This is the recommended replacement for Spring AutoReconfiguration library which is deprecated. See the `java-cfenv` repository for more details. -It also sets the 'cloud' profile for Spring Boot applications, as the Spring AutoReconfiguration framework did. +The included `java-cfenv` library activates the `cloud` Spring profile at runtime when `VCAP_SERVICES` is present, as the Spring AutoReconfiguration framework did. The buildpack itself does not set any Spring profile. + +The buildpack selects the appropriate `java-cfenv` version based on the detected Spring Boot major version: + +| Spring Boot | java-cfenv | +|-------------|------------| +| 3.x | 3.x (latest) | +| 4.x | 4.x (latest) | - - + + @@ -17,3 +24,32 @@ It also sets the 'cloud' profile for Spring Boot applications, as the Spring Aut
Detection CriterionExistence of a `Spring-Boot-Version: 3.*` manifest entryNo existing `java-cfenv` library foundExistence of a spring-boot-3.*.jar or spring-boot-4.*.jar in BOOT-INF/lib, WEB-INF/lib, or lib/; or a Spring-Boot-Version: 3.* / Spring-Boot-Version: 4.* entry in META-INF/MANIFEST.MFNo existing java-cfenv library found in the application
Tags
Tags are printed to standard output by the buildpack detect script + +## Configuration + +The framework can be disabled via the `JBP_CONFIG_JAVA_CF_ENV` environment variable: + +```bash +cf set-env JBP_CONFIG_JAVA_CF_ENV '{enabled: false}' +cf restage +``` + +The buildpack only re-reads this variable during staging, so a `cf restage` is required for the change to take effect. + +To re-enable, either set it back to `{enabled: true}` or remove the variable entirely: + +```bash +cf unset-env JBP_CONFIG_JAVA_CF_ENV +cf restage +``` + +| Variable | Default | Description | +|----------|---------|-------------| +| `JBP_CONFIG_JAVA_CF_ENV` | `{enabled: true}` | Enable or disable the framework | + +Note: if `java-cfenv*.jar` is already present in the application, the buildpack skips injection automatically — no need to disable explicitly for that case. + +Disable when: +- The application handles `VCAP_SERVICES` manually with custom binding logic +- The automatic `cloud` profile activation is unwanted +- Another service binding library conflicts with `java-cfenv` diff --git a/src/java/frameworks/java_cf_env.go b/src/java/frameworks/java_cf_env.go index 48bf3f91f2..7a70e04cec 100644 --- a/src/java/frameworks/java_cf_env.go +++ b/src/java/frameworks/java_cf_env.go @@ -71,7 +71,6 @@ func (j *JavaCfEnvFramework) Supply() error { } else { j.context.Log.Debug("Resolved Java CF Env version pattern '%s' to %s", versionPattern, resolvedVersion) } - // Install java-cfenv JAR javaCfEnvDir := filepath.Join(j.context.Stager.DepDir(), "java_cf_env") if err := j.context.Installer.InstallDependency(dep, javaCfEnvDir); err != nil { diff --git a/src/java/frameworks/java_cf_env_test.go b/src/java/frameworks/java_cf_env_test.go index b307be606f..b10f305699 100644 --- a/src/java/frameworks/java_cf_env_test.go +++ b/src/java/frameworks/java_cf_env_test.go @@ -68,10 +68,23 @@ var _ = Describe("Java CF Env", func() { }) }) - Context("with Spring Boot 3.x JAR in lib/", func() { + Context("with Spring Boot 4.1.x JAR in BOOT-INF/lib", func() { + BeforeEach(func() { + Expect(os.MkdirAll(filepath.Join(buildDir, "BOOT-INF", "lib"), 0755)).To(Succeed()) + Expect(os.WriteFile(filepath.Join(buildDir, "BOOT-INF", "lib", "spring-boot-4.1.0.jar"), []byte("fake"), 0644)).To(Succeed()) + }) + + It("returns 'Java CF Env'", func() { + name, err := fw.Detect() + Expect(err).NotTo(HaveOccurred()) + Expect(name).To(Equal("Java CF Env")) + }) + }) + + Context("with Spring Boot 4.1.x JAR in lib/", func() { BeforeEach(func() { Expect(os.MkdirAll(filepath.Join(buildDir, "lib"), 0755)).To(Succeed()) - Expect(os.WriteFile(filepath.Join(buildDir, "lib", "spring-boot-3.1.5.jar"), []byte("fake"), 0644)).To(Succeed()) + Expect(os.WriteFile(filepath.Join(buildDir, "lib", "spring-boot-4.1.0.jar"), []byte("fake"), 0644)).To(Succeed()) }) It("returns 'Java CF Env'", func() { @@ -81,10 +94,10 @@ var _ = Describe("Java CF Env", func() { }) }) - Context("with Spring Boot 3.x JAR in WEB-INF/lib", func() { + Context("with Spring Boot 4.1.x JAR in WEB-INF/lib", func() { BeforeEach(func() { Expect(os.MkdirAll(filepath.Join(buildDir, "WEB-INF", "lib"), 0755)).To(Succeed()) - Expect(os.WriteFile(filepath.Join(buildDir, "WEB-INF", "lib", "spring-boot-3.0.0.jar"), []byte("fake"), 0644)).To(Succeed()) + Expect(os.WriteFile(filepath.Join(buildDir, "WEB-INF", "lib", "spring-boot-4.1.0.jar"), []byte("fake"), 0644)).To(Succeed()) }) It("returns 'Java CF Env'", func() { @@ -94,12 +107,12 @@ var _ = Describe("Java CF Env", func() { }) }) - Context("with Spring-Boot-Version: 3.x in META-INF/MANIFEST.MF", func() { + Context("with Spring-Boot-Version: 4.1.x in META-INF/MANIFEST.MF", func() { BeforeEach(func() { Expect(os.MkdirAll(filepath.Join(buildDir, "META-INF"), 0755)).To(Succeed()) Expect(os.WriteFile( filepath.Join(buildDir, "META-INF", "MANIFEST.MF"), - []byte("Manifest-Version: 1.0\nSpring-Boot-Version: 3.2.0\nMain-Class: org.springframework.boot.loader.JarLauncher\n"), + []byte("Manifest-Version: 1.0\nSpring-Boot-Version: 4.1.0\nMain-Class: org.springframework.boot.loader.JarLauncher\n"), 0644, )).To(Succeed()) }) @@ -206,6 +219,12 @@ var _ = Describe("Java CF Env", func() { }) }) + Describe("DependencyIdentifier", func() { + It("returns java-cfenv so supply.go can look up the manifest default version", func() { + Expect(fw.DependencyIdentifier()).To(Equal("java-cfenv")) + }) + }) + Describe("Finalize", func() { Context("when the JAR is present", func() { BeforeEach(func() { diff --git a/src/java/supply/supply.go b/src/java/supply/supply.go index afcd8d0943..bc4d156805 100644 --- a/src/java/supply/supply.go +++ b/src/java/supply/supply.go @@ -181,5 +181,5 @@ func (s *Supplier) frameworkVersionSuffix(framework frameworks.Framework) string return "" } - return fmt.Sprintf(" (%s)", dependency.Version) + return fmt.Sprintf(" (default: %s)", dependency.Version) }