diff --git a/README.md b/README.md
index e563ea745d..e562ea1a34 100644
--- a/README.md
+++ b/README.md
@@ -126,6 +126,7 @@ The buildpack supports extension through the use of Git repository forking. The
* [Google Stackdriver Profiler](docs/framework-google_stackdriver_profiler.md) ([Configuration](docs/framework-google_stackdriver_profiler.md#configuration))
* [Introscope Agent](docs/framework-introscope_agent.md) ([Configuration](docs/framework-introscope_agent.md#configuration))
* [JaCoCo Agent](docs/framework-jacoco_agent.md) ([Configuration](docs/framework-jacoco_agent.md#configuration))
+ * [Java CfEnv](docs/framework-java-cfenv.md) ([Configuration](docs/framework-java-cfenv.md#configuration))
* [Java Memory Assistant](docs/framework-java_memory_assistant.md) ([Configuration](docs/framework-java_memory_assistant.md#configuration))
* [Java Options](docs/framework-java_opts.md) ([Configuration](docs/framework-java_opts.md#configuration))
* [JProfiler Profiler](docs/framework-jprofiler_profiler.md) ([Configuration](docs/framework-jprofiler_profiler.md#configuration))
diff --git a/config/components.yml b/config/components.yml
index 41d7bc1b73..79a60156fd 100644
--- a/config/components.yml
+++ b/config/components.yml
@@ -54,10 +54,11 @@ frameworks:
- "JavaBuildpack::Framework::Debug"
- "JavaBuildpack::Framework::DynatraceOneAgent"
- "JavaBuildpack::Framework::ElasticApmAgent"
-# - "JavaBuildpack::Framework::GoogleStackdriverDebugger"
+# - "JavaBuildpack::Framework::GoogleStackdriverDebugger"
- "JavaBuildpack::Framework::GoogleStackdriverProfiler"
- "JavaBuildpack::Framework::IntroscopeAgent"
- "JavaBuildpack::Framework::JacocoAgent"
+ - "JavaBuildpack::Framework::JavaCfEnv"
- "JavaBuildpack::Framework::JavaMemoryAssistant"
- "JavaBuildpack::Framework::Jmx"
- "JavaBuildpack::Framework::JprofilerProfiler"
diff --git a/config/java_cf_env.yml b/config/java_cf_env.yml
new file mode 100644
index 0000000000..a021138ff7
--- /dev/null
+++ b/config/java_cf_env.yml
@@ -0,0 +1,22 @@
+# Cloud Foundry Java Buildpack
+# Copyright 2013-2023 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Configuration for the Java CfEnv framework.
+# See https://github.com/pivotal-cf/java-cfenv for library information
+
+---
+version: 3.+
+repository_root: "{default.repository.root}/java-cfenv"
+enabled: true
diff --git a/config/packaging.yml b/config/packaging.yml
index aed29fdc22..8818f0c517 100644
--- a/config/packaging.yml
+++ b/config/packaging.yml
@@ -82,6 +82,10 @@ jacoco_agent:
name: JaCoCo Agent
release_notes: '[Release Notes](https://github.com/jacoco/jacoco/releases)'
+java_cf_env:
+ name: Java CFEnv
+ release_notes: '[Release Notes](https://github.com/pivotal-cf/java-cfenv/releases)'
+
jprofiler_profiler:
name: JProfiler Profiler
release_notes: '[ChangeLog](https://www.ej-technologies.com/download/jprofiler/changelog.html)'
diff --git a/docs/framework-java-cfenv.md b/docs/framework-java-cfenv.md
new file mode 100644
index 0000000000..1e1fe474a7
--- /dev/null
+++ b/docs/framework-java-cfenv.md
@@ -0,0 +1,19 @@
+# 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.
+
+This is the recommended replacement for Spring AutoReconfiguration library which is deprecated. See the `java-cfenv` repostitory for more detail.
+
+It also sets the 'cloud' profile for Spring Boot applications, as the Spring AutoReconfiguration framework did.
+
+
+
+ | Detection Criterion |
+ Existence of a spring-boot-3*.jar file in the application directory or a `Spring-Boot-Version: 3.*` manifest entry |
+ No existing `java-cfenv` library found |
+
+
+ | Tags |
+ java-cf-env=<version> |
+
+
+Tags are printed to standard output by the buildpack detect script
diff --git a/lib/java_buildpack/framework/java_cf_env.rb b/lib/java_buildpack/framework/java_cf_env.rb
new file mode 100644
index 0000000000..3b3644a040
--- /dev/null
+++ b/lib/java_buildpack/framework/java_cf_env.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+# Cloud Foundry Java Buildpack
+# Copyright 2013-2020 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'java_buildpack/component/versioned_dependency_component'
+require 'java_buildpack/framework'
+require 'java_buildpack/util/spring_boot_utils'
+
+module JavaBuildpack
+ module Framework
+
+ # Encapsulates the detect, compile, and release functionality for enabling cloud auto-reconfiguration in Spring
+ # applications.
+ class JavaCfEnv < JavaBuildpack::Component::VersionedDependencyComponent
+ include JavaBuildpack::Util
+
+ def initialize(context)
+ @spring_boot_utils = JavaBuildpack::Util::SpringBootUtils.new
+ super(context)
+ end
+
+ # (see JavaBuildpack::Component::BaseComponent#compile)
+ def compile
+ download_jar
+ @droplet.additional_libraries << (@droplet.sandbox + jar_name)
+ end
+
+ # (see JavaBuildpack::Component::BaseComponent#release)
+ def release
+ @droplet.additional_libraries << (@droplet.sandbox + jar_name)
+ end
+
+ protected
+
+ # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?)
+ def supports?
+ @configuration['enabled'] && spring_boot_3? && !java_cfenv?
+ end
+
+ private
+
+ def spring_boot_3?
+ @spring_boot_utils.is?(@application) && Gem::Version.new((@spring_boot_utils.version @application)).release >=
+ Gem::Version.new('3.0.0')
+ end
+
+ def java_cfenv?
+ (@droplet.root + '**/*java-cfenv*.jar').glob.any?
+ end
+
+ end
+ end
+end
diff --git a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb
index 80b20ca027..f53646e240 100644
--- a/lib/java_buildpack/framework/spring_auto_reconfiguration.rb
+++ b/lib/java_buildpack/framework/spring_auto_reconfiguration.rb
@@ -33,6 +33,7 @@ def initialize(context)
# (see JavaBuildpack::Component::BaseComponent#compile)
def compile
log_warning_scc_manual if spring_cloud_connectors?
+ return if java_cf_env_framework?
download_jar
@droplet.additional_libraries << (@droplet.sandbox + jar_name)
@@ -42,6 +43,8 @@ def compile
# (see JavaBuildpack::Component::BaseComponent#release)
def release
+ return if java_cf_env_framework?
+
@droplet.additional_libraries << (@droplet.sandbox + jar_name)
end
@@ -59,7 +62,13 @@ def spring?
end
def java_cfenv?
- (@droplet.root + '**/*java-cfenv*.jar').glob.any?
+ (@droplet.root + '**/*java-cfenv*.jar').glob.any? || java_cf_env_framework?
+ end
+
+ def java_cf_env_framework?
+ @droplet.additional_libraries.any? do |additional_library|
+ additional_library.instance_variable_get(:@pathname).fnmatch?('*java_cf_env*.jar')
+ end
end
def spring_cloud_connectors?
diff --git a/spec/fixtures/framework_java_cf_boot_2/META-INF/MANIFEST.MF b/spec/fixtures/framework_java_cf_boot_2/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..ce0077f4ce
--- /dev/null
+++ b/spec/fixtures/framework_java_cf_boot_2/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Spring-Boot-Lib: manifest-lib-value/
+Main-Class: org.springframework.boot.loader.JarLauncher
+Spring-Boot-Version: 2.1.0.RELEASE
diff --git a/spec/fixtures/framework_java_cf_boot_2/WEB-INF/lib/spring-boot-1.0.0.RELEASE.jar b/spec/fixtures/framework_java_cf_boot_2/WEB-INF/lib/spring-boot-1.0.0.RELEASE.jar
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/spec/fixtures/framework_java_cf_boot_3/META-INF/MANIFEST.MF b/spec/fixtures/framework_java_cf_boot_3/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..a64827339d
--- /dev/null
+++ b/spec/fixtures/framework_java_cf_boot_3/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Spring-Boot-Lib: manifest-lib-value/
+Main-Class: org.springframework.boot.loader.JarLauncher
+Spring-Boot-Version: 3.0.0.M1
diff --git a/spec/fixtures/framework_java_cf_boot_3/WEB-INF/lib/spring-boot-3.0.0.M1.jar b/spec/fixtures/framework_java_cf_boot_3/WEB-INF/lib/spring-boot-3.0.0.M1.jar
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/spec/fixtures/framework_java_cf_exists/META-INF/MANIFEST.MF b/spec/fixtures/framework_java_cf_exists/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..47eb0c27e7
--- /dev/null
+++ b/spec/fixtures/framework_java_cf_exists/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Spring-Boot-Lib: manifest-lib-value/
+Spring-Boot-Version: 3.2.5.RELEASE
+Main-Class: org.springframework.boot.loader.JarLauncher
+
diff --git a/spec/fixtures/framework_java_cf_exists/WEB-INF/lib/java-cfenv-2.1.2.RELEASE.jar b/spec/fixtures/framework_java_cf_exists/WEB-INF/lib/java-cfenv-2.1.2.RELEASE.jar
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/spec/fixtures/framework_java_cf_exists/WEB-INF/lib/java-cfenv-boot-2.1.2.RELEASE.jar b/spec/fixtures/framework_java_cf_exists/WEB-INF/lib/java-cfenv-boot-2.1.2.RELEASE.jar
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/spec/fixtures/framework_java_cf_exists/WEB-INF/lib/java-cfenv-jdbc-2.1.2.RELEASE.jar b/spec/fixtures/framework_java_cf_exists/WEB-INF/lib/java-cfenv-jdbc-2.1.2.RELEASE.jar
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/spec/fixtures/framework_java_cf_exists/WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar b/spec/fixtures/framework_java_cf_exists/WEB-INF/lib/spring-boot-3.2.3.RELEASE.jar
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/spec/fixtures/stub-java-cfenv.jar b/spec/fixtures/stub-java-cfenv.jar
new file mode 100644
index 0000000000..0878c3ccb5
Binary files /dev/null and b/spec/fixtures/stub-java-cfenv.jar differ
diff --git a/spec/java_buildpack/framework/java_cfenv_spec.rb b/spec/java_buildpack/framework/java_cfenv_spec.rb
new file mode 100644
index 0000000000..bfd67e7729
--- /dev/null
+++ b/spec/java_buildpack/framework/java_cfenv_spec.rb
@@ -0,0 +1,76 @@
+# frozen_string_literal: true
+
+# Cloud Foundry Java Buildpack
+# Copyright 2013-2020 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'spec_helper'
+require 'component_helper'
+require 'logging_helper'
+require 'java_buildpack/framework/java_cf_env'
+
+describe JavaBuildpack::Framework::JavaCfEnv do
+ include_context 'with component help'
+ include_context 'with console help'
+ include_context 'with logging help'
+
+ let(:configuration) { { 'enabled' => true } }
+
+ it 'detects with Spring Boot 3 JAR',
+ app_fixture: 'framework_java_cf_boot_3' do
+
+ expect(component.detect).to eq("java-cf-env=#{version}")
+ end
+
+ it 'does not detect with Spring Boot < 3',
+ app_fixture: 'framework_java_cf_boot_2' do
+
+ expect(component.detect).to be_nil
+ end
+
+ it 'does not detect with Spring Boot 3 & java-cfenv present',
+ app_fixture: 'framework_java_cf_exists' do
+
+ expect(component.detect).to be_nil
+ end
+
+ context do
+ let(:configuration) { { 'enabled' => false } }
+
+ it 'does not detect if disabled',
+ app_fixture: 'framework_java_cf_boot_3' do
+
+ expect(component.detect).to be_nil
+ end
+ end
+
+ it 'downloads additional libraries',
+ app_fixture: 'framework_java_cf_boot_3',
+ cache_fixture: 'stub-java-cfenv.jar' do
+
+ component.compile
+
+ expect(sandbox + "java_cf_env-#{version}.jar").to exist
+ end
+
+ it 'adds to additional libraries',
+ app_fixture: 'framework_java_cf_boot_3',
+ cache_fixture: 'stub-java-cfenv.jar' do
+
+ component.release
+
+ expect(additional_libraries).to include(sandbox + "java_cf_env-#{version}.jar")
+ end
+
+end
diff --git a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb
index d3f5cec59c..17a2946b04 100644
--- a/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb
+++ b/spec/java_buildpack/framework/spring_auto_reconfiguration_spec.rb
@@ -39,7 +39,7 @@
expect(component.detect).to eq("spring-auto-reconfiguration=#{version}")
end
- it 'does not detect with Spring JAR and java-cfenv',
+ it 'does not detect with Spring JAR and user java-cfenv',
app_fixture: 'framework_auto_reconfiguration_java_cfenv' do
expect(component.detect).to be_nil
@@ -104,4 +104,21 @@
expect(additional_libraries).to include(sandbox + "spring_auto_reconfiguration-#{version}.jar")
end
+ context('when java-cfenv injects its lib') do
+
+ before do
+ additional_libraries.insert 0, additional_libs_directory + 'java_cf_env.jar'
+ end
+
+ after do
+ additional_libraries.delete additional_libs_directory + 'java_cf_env.jar'
+ end
+
+ it 'does not detect with Spring JAR and injected cfenv',
+ app_fixture: 'framework_auto_reconfiguration_servlet_3' do
+
+ expect(component.detect).to be_nil
+ end
+
+ end
end