diff --git a/itests/tomee-microprofile-itests/pom.xml b/itests/tomee-microprofile-itests/pom.xml
index 4eafe3091e8..0b2dad99e8e 100644
--- a/itests/tomee-microprofile-itests/pom.xml
+++ b/itests/tomee-microprofile-itests/pom.xml
@@ -77,11 +77,47 @@
+
+ org.apache.tomee
+ apache-tomee
+ ${project.version}
+ tar.gz
+ plus
+
+
+ *
+ *
+
+
+
+
+ org.apache.tomee
+ apache-tomee
+ ${project.version}
+ tar.gz
+ plume
+
+
+ *
+ *
+
+
+
org.apache.tomee
jakartaee-api
provided
+
+ io.opentelemetry
+ opentelemetry-api
+ provided
+
+
+ io.opentelemetry.instrumentation
+ opentelemetry-instrumentation-annotations
+ provided
+
org.eclipse.microprofile.openapi
microprofile-openapi-api
diff --git a/itests/tomee-microprofile-itests/src/main/java/org/apache/tomee/microprofile/telemetry/TelemetryApp.java b/itests/tomee-microprofile-itests/src/main/java/org/apache/tomee/microprofile/telemetry/TelemetryApp.java
new file mode 100644
index 00000000000..fc0f70e6e27
--- /dev/null
+++ b/itests/tomee-microprofile-itests/src/main/java/org/apache/tomee/microprofile/telemetry/TelemetryApp.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.tomee.microprofile.telemetry;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.ws.rs.ApplicationPath;
+import jakarta.ws.rs.core.Application;
+
+@ApplicationScoped
+@ApplicationPath("/api")
+public class TelemetryApp extends Application {
+}
diff --git a/itests/tomee-microprofile-itests/src/main/java/org/apache/tomee/microprofile/telemetry/WeatherGateway.java b/itests/tomee-microprofile-itests/src/main/java/org/apache/tomee/microprofile/telemetry/WeatherGateway.java
new file mode 100644
index 00000000000..4b9caab5429
--- /dev/null
+++ b/itests/tomee-microprofile-itests/src/main/java/org/apache/tomee/microprofile/telemetry/WeatherGateway.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.tomee.microprofile.telemetry;
+
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.instrumentation.annotations.SpanAttribute;
+import io.opentelemetry.instrumentation.annotations.WithSpan;
+import jakarta.enterprise.context.RequestScoped;
+import jakarta.inject.Inject;
+
+@RequestScoped
+public class WeatherGateway {
+
+ @Inject
+ private Span span;
+
+ @WithSpan("weather.forecast")
+ public String forecast(@SpanAttribute("weather.city") final String city) {
+ span.setAttribute("weather.source", "AccuWeather");
+ return "Sunny in " + city;
+ }
+}
diff --git a/itests/tomee-microprofile-itests/src/main/java/org/apache/tomee/microprofile/telemetry/WeatherResource.java b/itests/tomee-microprofile-itests/src/main/java/org/apache/tomee/microprofile/telemetry/WeatherResource.java
new file mode 100644
index 00000000000..84edd82e289
--- /dev/null
+++ b/itests/tomee-microprofile-itests/src/main/java/org/apache/tomee/microprofile/telemetry/WeatherResource.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.tomee.microprofile.telemetry;
+
+import jakarta.enterprise.context.RequestScoped;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+
+@Path("weather")
+@RequestScoped
+public class WeatherResource {
+
+ @Inject
+ private WeatherGateway gateway;
+
+ @GET
+ @Path("/forecast/{city}")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String forecast(@PathParam("city") final String city) {
+ return gateway.forecast(city);
+ }
+}
diff --git a/itests/tomee-microprofile-itests/src/test/java/org/apache/tomee/microprofile/telemetry/TelemetryConfigFileTest.java b/itests/tomee-microprofile-itests/src/test/java/org/apache/tomee/microprofile/telemetry/TelemetryConfigFileTest.java
new file mode 100644
index 00000000000..cc43e6e1202
--- /dev/null
+++ b/itests/tomee-microprofile-itests/src/test/java/org/apache/tomee/microprofile/telemetry/TelemetryConfigFileTest.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.tomee.microprofile.telemetry;
+
+import jakarta.ws.rs.core.Response;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.tomee.server.composer.Archive;
+import org.apache.tomee.server.composer.TomEE;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.tomitribe.util.IO;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(Parameterized.class)
+public class TelemetryConfigFileTest {
+
+ private static final String OTEL_CONFIG_YAML = String.join("\n",
+ "file_format: \"1.0\"",
+ "disabled: false",
+ "");
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Object[][] distributions() {
+ return new Object[][]{
+ {"microprofile"},
+ {"plus"},
+ {"plume"},
+ };
+ }
+
+ private final String classifier;
+
+ public TelemetryConfigFileTest(final String classifier) {
+ this.classifier = classifier;
+ }
+
+ private TomEE.Builder distribution() throws Exception {
+ switch (classifier) {
+ case "microprofile":
+ return TomEE.microprofile();
+ case "plus":
+ return TomEE.plus();
+ case "plume":
+ // server-composer has no plume() shortcut; resolve it explicitly.
+ // "version" is exported as a system property by surefire (pom.xml).
+ return TomEE.of("org.apache.tomee:apache-tomee:tar.gz:plume:" + System.getProperty("version"));
+ default:
+ throw new IllegalArgumentException("Unknown classifier: " + classifier);
+ }
+ }
+
+ @Test
+ public void telemetryAppDeploysWithConfigFileSet() throws Exception {
+ final File appJar = Archive.archive()
+ .add(TelemetryApp.class)
+ .add(WeatherResource.class)
+ .add(WeatherGateway.class)
+ .asJar();
+
+ final List declarativeConfigErrors = new ArrayList<>();
+
+ final TomEE.Builder builder = distribution()
+ .add("conf/otel-config.yaml", OTEL_CONFIG_YAML)
+ .add("webapps/test/WEB-INF/beans.xml", "")
+ .add("webapps/test/WEB-INF/lib/app.jar", appJar)
+ .watch("declarative-config", "\n", declarativeConfigErrors::add);
+
+ builder.home(home -> builder.env("CATALINA_OPTS",
+ "-Dtomee.mp.scan=all"
+ + " -Dotel.config.file=" + new File(home, "conf/otel-config.yaml").getAbsolutePath()));
+
+ final TomEE tomee = builder.build();
+ try {
+ final Response response = WebClient.create(tomee.toURI().toString())
+ .path("/test/api/weather/forecast/London")
+ .get();
+
+ assertEquals(classifier + ": telemetry app did not deploy with otel.config.file set"
+ + " (missing opentelemetry-sdk-extension-declarative-config?) " + declarativeConfigErrors,
+ 200, response.getStatus());
+ assertEquals("Sunny in London", IO.slurp(response.readEntity(java.io.InputStream.class)));
+ assertTrue(classifier + ": OpenTelemetry declarative-config failure in server log " + declarativeConfigErrors,
+ declarativeConfigErrors.isEmpty());
+ } finally {
+ tomee.shutdown();
+ }
+ }
+}
diff --git a/pom.xml b/pom.xml
index 49524ff4e45..73f3abf110d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -192,6 +192,9 @@
4.0.4
4.2.4
2.15.1
+ 1.62.0
+ 2.27.0
+ 1.62.0-alpha
2.22.1
@@ -1916,6 +1919,22 @@
snakeyaml
${version.snakeyaml}
+
+
+ io.opentelemetry
+ opentelemetry-api
+ ${version.opentelemetry}
+
+
+ io.opentelemetry
+ opentelemetry-sdk-extension-declarative-config
+ ${version.opentelemetry.declarative-config}
+
+
+ io.opentelemetry.instrumentation
+ opentelemetry-instrumentation-annotations
+ ${version.opentelemetry.instrumentation}
+
diff --git a/tomee/tomee-microprofile/mp-common/pom.xml b/tomee/tomee-microprofile/mp-common/pom.xml
index cc8cc91a735..6a18adc8825 100644
--- a/tomee/tomee-microprofile/mp-common/pom.xml
+++ b/tomee/tomee-microprofile/mp-common/pom.xml
@@ -292,6 +292,11 @@
+
+ io.opentelemetry
+ opentelemetry-sdk-extension-declarative-config
+
+
com.fasterxml.jackson.dataformat