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
42 changes: 37 additions & 5 deletions docs/framework-java-cfenv.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,51 @@
# 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 CloudFoundry 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` <a href="https://github.com/pivotal-cf/java-cfenv">repostitory</a> for more detail.
This is the recommended replacement for Spring AutoReconfiguration library which is deprecated. See the `java-cfenv` <a href="https://github.com/pivotal-cf/java-cfenv">repository</a> for more detail.

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) |

<table>
<tr>
<td><strong>Detection Criterion</strong></td>
<td>Existence of a `Spring-Boot-Version: 3.*` manifest entry</td>
<td>No existing `java-cfenv` library found</td>
<td>Existence of a <tt>spring-boot-3.*.jar</tt> or <tt>spring-boot-4.*.jar</tt> in <tt>BOOT-INF/lib</tt>, <tt>WEB-INF/lib</tt>, or <tt>lib/</tt>; or a <tt>Spring-Boot-Version: 3.*</tt> / <tt>Spring-Boot-Version: 4.*</tt> entry in <tt>META-INF/MANIFEST.MF</tt></td>
<td>No existing <tt>java-cfenv</tt> library found in the application</td>
</tr>
<tr>
<td><strong>Tags</strong></td>
<td><tt>java-cf-env=&lt;version&gt;</tt></td>
</tr>
</table>
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 <app> JBP_CONFIG_JAVA_CF_ENV '{enabled: false}'
```

To re-enable, either set it back to `{enabled: true}` or remove the variable entirely:

```bash
cf unset-env <app> JBP_CONFIG_JAVA_CF_ENV
```

| 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`
1 change: 0 additions & 1 deletion src/java/frameworks/java_cf_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
31 changes: 25 additions & 6 deletions src/java/frameworks/java_cf_env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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() {
Expand All @@ -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())
})
Expand Down Expand Up @@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion src/java/supply/supply.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}