diff --git a/config/components.yml b/config/components.yml
index 79a60156fd..90a12ec28e 100644
--- a/config/components.yml
+++ b/config/components.yml
@@ -67,6 +67,7 @@ frameworks:
- "JavaBuildpack::Framework::MariaDbJDBC"
- "JavaBuildpack::Framework::MetricWriter"
- "JavaBuildpack::Framework::NewRelicAgent"
+ - "JavaBuildpack::Framework::OpenTelemetryJavaagent"
- "JavaBuildpack::Framework::PostgresqlJDBC"
- "JavaBuildpack::Framework::RiverbedAppinternalsAgent"
- "JavaBuildpack::Framework::SealightsAgent"
diff --git a/config/open_telemetry_javaagent.yml b/config/open_telemetry_javaagent.yml
new file mode 100644
index 0000000000..2e45e5713e
--- /dev/null
+++ b/config/open_telemetry_javaagent.yml
@@ -0,0 +1,19 @@
+# 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 OpenTelemetry Javaagent
+---
+version: +
+repository_root: https://raw.githubusercontent.com/open-telemetry/opentelemetry-java-instrumentation/cloudfoundry/
diff --git a/docs/framework-open_telemetry_javaagent.md b/docs/framework-open_telemetry_javaagent.md
new file mode 100644
index 0000000000..804d2e118f
--- /dev/null
+++ b/docs/framework-open_telemetry_javaagent.md
@@ -0,0 +1,48 @@
+# OpenTelemetry Javaagent
+
+The OpenTelemetry Javaagent buildpack framework will cause an application to be automatically instrumented
+with the [OpenTelemetry Javaagent Instrumentation](https://github.com/open-telemetry/opentelemetry-java-instrumentation).
+
+Data will be sent directly to the OpenTelemetry Collector.
+
+
+
+ | Detection Criterion |
+ Existence of a bound service containing the string otel-collector |
+
+
+ | Tags |
+ opentelemetry-javaagent=<version> |
+
+
+
+Tags are printed to standard output by the buildpack detect script
+
+## User-Provided Service
+
+Users are currently expected to `create-user-provided-service` (cups) of the collector
+and bind it to their application. The service MUST contain the string `otel-collector`.
+
+For example, to create a service named `otel-collector` that represents an environment named `cf-demo`, you could use the following commands:
+
+```
+$ cf cups otel-collector -p '{"otel.resource.attributes": "deployment.environment=cf-demo"}'
+$ cf bind-service myApp otel-collector
+$ cf restage myApp
+```
+
+### Choosing a version
+
+Most users should skip this and simply use the latest version of the agent available (the default).
+To override the default and choose a specific version, you can use the `JBP_CONFIG_*` mechanism
+and set the `JBP_CONFIG_OPENTELEMETRY_JAVAAGENT` environment variable for your application.
+
+For example, to use version 1.27.0 of the OpenTelemetry Javaagent Instrumentation, you
+could run:
+```
+$ cf set-env testapp JBP_CONFIG_OPENTELEMETRY_JAVAAGENT '{version: 1.27.0}'
+```
+
+# Additional Resources
+
+* [OpenTelemetry Javaagent Instrumentation](https://github.com/open-telemetry/opentelemetry-java-instrumentation) on GitHub
diff --git a/docs/framework-splunk_otel_java_agent.md b/docs/framework-splunk_otel_java_agent.md
index 0ba30e97d5..e8b438376b 100644
--- a/docs/framework-splunk_otel_java_agent.md
+++ b/docs/framework-splunk_otel_java_agent.md
@@ -20,8 +20,8 @@ Tags are printed to standard output by the buildpack detect script
## User-Provided Service
-Users are currently expected to provide their own "custom user provided service" (cups)
-instance and bind it to their application. The service MUST contain the string `splunk-o11y`.
+Users are currently expected to `create-user-provided-service` (cups) of the collector
+and bind it to their application. The service MUST contain the string `splunk-o11y`.
For example, to create a service named `splunk-o11y` that represents Observability Cloud
realm `us0` and represents a user environment named `cf-demo`, you could use the following
diff --git a/lib/java_buildpack/framework/open_telemetry_javaagent.rb b/lib/java_buildpack/framework/open_telemetry_javaagent.rb
new file mode 100644
index 0000000000..b78049bbf2
--- /dev/null
+++ b/lib/java_buildpack/framework/open_telemetry_javaagent.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+# 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.
+
+require 'java_buildpack/component/versioned_dependency_component'
+require 'java_buildpack/framework'
+
+module JavaBuildpack
+ module Framework
+
+ # Main class for adding the OpenTelemetry Javaagent instrumentation
+ class OpenTelemetryJavaagent < JavaBuildpack::Component::VersionedDependencyComponent
+
+ # (see JavaBuildpack::Component::BaseComponent#compile)
+ def compile
+ download_jar
+ end
+
+ # (see JavaBuildpack::Component::BaseComponent#release)
+ def release
+ java_opts = @droplet.java_opts
+ java_opts.add_javaagent(@droplet.sandbox + jar_name)
+
+ credentials = @application.services.find_service(REQUIRED_SERVICE_NAME_FILTER)['credentials']
+ # Add all otel.* credentials from the service bind as jvm system properties
+ credentials&.each do |key, value|
+ java_opts.add_system_property(key, value) if key.start_with?('otel.')
+ end
+
+ # Set the otel.service.name to the application_name if not specified in credentials
+ return if credentials.key? 'otel.service.name'
+
+ # Set the otel.service.name to the application_name
+ app_name = @application.details['application_name']
+ java_opts.add_system_property('otel.service.name', app_name)
+ end
+
+ protected
+
+ # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?)
+ def supports?
+ @application.services.one_service? REQUIRED_SERVICE_NAME_FILTER
+ end
+
+ # bound service must contain the string `otel-collector`
+ REQUIRED_SERVICE_NAME_FILTER = /otel-collector/.freeze
+
+ end
+ end
+end
diff --git a/spec/java_buildpack/framework/open_telemetry_javaagent_spec.rb b/spec/java_buildpack/framework/open_telemetry_javaagent_spec.rb
new file mode 100644
index 0000000000..940e5decff
--- /dev/null
+++ b/spec/java_buildpack/framework/open_telemetry_javaagent_spec.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 'spec_helper'
+require 'component_helper'
+require 'java_buildpack/framework/open_telemetry_javaagent'
+require 'java_buildpack/util/tokenized_version'
+
+describe JavaBuildpack::Framework::OpenTelemetryJavaagent do
+ include_context 'with component help'
+
+ let(:configuration) { { 'version' => '1.27.0' } }
+ let(:vcap_application) { { 'application_name' => 'GreatServiceTM' } }
+
+ it 'does not detect without otel-collector service bind' do
+ expect(component.detect).to be_nil
+ end
+
+ context 'when detected' do
+
+ before do
+ allow(services).to receive(:one_service?).with(/otel-collector/).and_return(true)
+ end
+
+ it 'detects with opentelemetry-javaagent' do
+ expect(component.detect).to eq("open-telemetry-javaagent=#{version}")
+ end
+
+ it 'downloads the opentelemetry javaagent jar', cache_fixture: 'stub-download.jar' do
+
+ component.compile
+
+ expect(sandbox + "open_telemetry_javaagent-#{version}.jar").to exist
+ end
+
+ it 'updates JAVA_OPTS' do
+ component.release
+
+ expect(java_opts).to include(
+ "-javaagent:$PWD/.java-buildpack/open_telemetry_javaagent/open_telemetry_javaagent-#{version}.jar"
+ )
+ end
+
+ it 'sets the service name from the application name' do
+ component.release
+
+ expect(java_opts).to include('-Dotel.service.name=GreatServiceTM')
+ end
+
+ end
+
+end