All Products
Search
Document Center

Managed Service for OpenTelemetry:Report trace data from Java applications by using OpenTelemetry

Last Updated:Mar 11, 2026

Managed Service for OpenTelemetry collects trace data from Java applications and provides application topology, traces, abnormal and slow transaction analysis, and SQL analysis. Three instrumentation approaches are available, from zero-code agent setup to full SDK control.

ApproachEffortWhen to use
OpenTelemetry Java agent (recommended)Minimal -- attach a JAR, no code changesMost applications. Start here.
OpenTelemetry SDK for JavaModerate -- write instrumentation codeCustom spans, attributes, or unsupported frameworks
Agent + SDK combinedModerate -- agent handles the basics, SDK adds custom spansAutomatic coverage plus targeted custom instrumentation

Sample code

Clone or browse the sample project for a working reference:

git clone https://github.com/alibabacloud-observability/java-demo.git
cd java-demo/opentelemetry-demo

Method 1: Automatic instrumentation with the OpenTelemetry Java agent

The OpenTelemetry Java agent attaches to your JVM at startup and instruments hundreds of libraries and frameworks without any code changes. This is the recommended starting point for most applications.

Step 1: Download the agent

Download the latest agent JAR from GitHub Releases:

# wget
wget -O opentelemetry-javaagent.jar \
  https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar

# or curl
curl -Lo opentelemetry-javaagent.jar \
  https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar

Step 2: Configure JVM parameters and start the application

Add the -javaagent flag before the -jar argument. Choose either the HTTP or gRPC protocol.

HTTP

java -javaagent:/path/to/opentelemetry-javaagent.jar \
  -Dotel.resource.attributes=service.name=<your-service-name>,service.version=<your-version>,deployment.environment=<your-env> \
  -Dotel.exporter.otlp.protocol=http/protobuf \
  -Dotel.exporter.otlp.traces.endpoint=<traces-endpoint> \
  -Dotel.exporter.otlp.metrics.endpoint=<metrics-endpoint> \
  -Dotel.logs.exporter=none \
  -jar /path/to/your/app.jar

Replace the placeholders with your actual values:

PlaceholderDescriptionExample
<your-service-name>A name that identifies your applicationorder-service
<your-version>Application version1.0.0
<your-env>Deployment environmentproduction
<traces-endpoint>Trace endpoint from the Prerequisites sectionhttp://tracing-analysis-dc-hz-internal.aliyuncs.com/adapt_ggxw4l****@7323a5caae3****_ggxw4l****@53df7ad2afe****/api/otlp/traces
<metrics-endpoint>Metric endpoint from the Prerequisites sectionhttp://tracing-analysis-dc-hz-internal.aliyuncs.com/adapt_ggxw4l****@7323a5caae3****_ggxw4l****@53df7ad2afe****/api/otlp/metrics

Example:

java -javaagent:/path/to/opentelemetry-javaagent.jar \
  -Dotel.resource.attributes=service.name=order-service,service.version=1.0.0,deployment.environment=production \
  -Dotel.exporter.otlp.protocol=http/protobuf \
  -Dotel.exporter.otlp.traces.endpoint=http://tracing-analysis-dc-hz-internal.aliyuncs.com/adapt_ggxw4l****@7323a5caae3****_ggxw4l****@53df7ad2afe****/api/otlp/traces \
  -Dotel.exporter.otlp.metrics.endpoint=http://tracing-analysis-dc-hz-internal.aliyuncs.com/adapt_ggxw4l****@7323a5caae3****_ggxw4l****@53df7ad2afe****/api/otlp/metrics \
  -Dotel.logs.exporter=none \
  -jar /path/to/your/app.jar

gRPC

java -javaagent:/path/to/opentelemetry-javaagent.jar \
  -Dotel.resource.attributes=service.name=<your-service-name>,service.version=<your-version>,deployment.environment=<your-env> \
  -Dotel.exporter.otlp.protocol=grpc \
  -Dotel.exporter.otlp.headers=Authentication=<token> \
  -Dotel.exporter.otlp.endpoint=<endpoint> \
  -Dotel.logs.exporter=none \
  -jar /path/to/your/app.jar

Replace the placeholders with your actual values:

PlaceholderDescriptionExample
<token>Authentication token from the Prerequisites sectionggxw4l****@7323a5caae3****_ggxw4l****@53df7ad2afe****
<endpoint>gRPC endpoint from the Prerequisites sectionhttp://tracing-analysis-dc-hz-internal.aliyuncs.com:8090

Example:

java -javaagent:/path/to/opentelemetry-javaagent.jar \
  -Dotel.resource.attributes=service.name=order-service,service.version=1.0.0,deployment.environment=production \
  -Dotel.exporter.otlp.protocol=grpc \
  -Dotel.exporter.otlp.headers=Authentication=ggxw4l****@7323a5caae3****_ggxw4l****@53df7ad2afe**** \
  -Dotel.exporter.otlp.endpoint=http://tracing-analysis-dc-hz-internal.aliyuncs.com:8090 \
  -Dotel.logs.exporter=none \
  -jar /path/to/your/app.jar
To forward trace data through an OpenTelemetry Collector, remove -Dotel.exporter.otlp.headers=Authentication=<token> and set <endpoint> to the Collector address on your on-premises machine.

Step 3: Verify trace data

  1. Open the Managed Service for OpenTelemetry console.

  2. On the Applications page, click your application name.

  3. Confirm that traces appear on the application details page.

Troubleshooting:

  • If no data appears, verify that the endpoint and token are correct.

  • Enable debug logging to inspect the agent behavior:

      -Dotel.javaagent.debug=true
  • Temporarily disable the agent without removing it from the startup command:

      -Dotel.javaagent.enabled=false

Method 2: Manual instrumentation with OpenTelemetry SDK for Java

Use OpenTelemetry SDK for Java when you need full control over which operations produce spans, what attributes they carry, or when the automatic agent does not cover your framework.

Step 1: Add Maven dependencies

Add the following to your pom.xml:

<dependencies>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-api</artifactId>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-sdk-trace</artifactId>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-exporter-otlp</artifactId>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-sdk</artifactId>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-semconv</artifactId>
        <version>1.30.0-alpha</version>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-bom</artifactId>
            <version>1.30.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Step 2: Initialize the tracer

Create a helper class that configures the exporter, resource attributes, and tracer. Select the protocol that matches your environment.

HTTP

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;

public class OpenTelemetrySupport {

    static {
        // Define the resource that describes this service
        Resource resource = Resource.getDefault()
                .merge(Resource.create(Attributes.of(
                        ResourceAttributes.SERVICE_NAME, "<your-service-name>",
                        ResourceAttributes.SERVICE_VERSION, "<your-version>",
                        ResourceAttributes.DEPLOYMENT_ENVIRONMENT, "<your-env>",
                        ResourceAttributes.HOST_NAME, "<your-host-name>"
                )));

        // Build a tracer provider with the OTLP HTTP exporter
        SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
                .addSpanProcessor(BatchSpanProcessor.builder(OtlpHttpSpanExporter.builder()
                        .setEndpoint("<endpoint>")  // Trace endpoint from the Prerequisites section
                        .build()).build())
                .setResource(resource)
                .build();

        // Register the SDK globally
        OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
                .setTracerProvider(sdkTracerProvider)
                .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
                .buildAndRegisterGlobal();

        tracer = openTelemetry.getTracer("OpenTelemetry Tracer", "1.0.0");
    }

    private static Tracer tracer;

    public static Tracer getTracer() {
        return tracer;
    }
}

gRPC

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;

public class OpenTelemetrySupport {

    static {
        // Define the resource that describes this service
        Resource resource = Resource.getDefault()
                .merge(Resource.create(Attributes.of(
                        ResourceAttributes.SERVICE_NAME, "<your-service-name>",
                        ResourceAttributes.SERVICE_VERSION, "<your-version>",
                        ResourceAttributes.DEPLOYMENT_ENVIRONMENT, "<your-env>",
                        ResourceAttributes.HOST_NAME, "<your-host-name>"
                )));

        // Build a tracer provider with the OTLP gRPC exporter
        SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
                .addSpanProcessor(BatchSpanProcessor.builder(OtlpGrpcSpanExporter.builder()
                        .setEndpoint("<endpoint>")         // gRPC endpoint from the Prerequisites section
                        .addHeader("Authentication", "<token>")  // Authentication token from the Prerequisites section
                        .build()).build())
                .setResource(resource)
                .build();

        // Register the SDK globally
        OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
                .setTracerProvider(sdkTracerProvider)
                .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
                .buildAndRegisterGlobal();

        tracer = openTelemetry.getTracer("OpenTelemetry Tracer", "1.0.0");
    }

    private static Tracer tracer;

    public static Tracer getTracer() {
        return tracer;
    }
}

Step 3: Create spans

Use the tracer to create parent and child spans. Each span captures a unit of work, along with any attributes and error status.

import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.context.Scope;

public class Main {

    public static void parentMethod() {
        // Start a parent span
        Span span = OpenTelemetrySupport.getTracer().spanBuilder("parent span").startSpan();
        try (Scope scope = span.makeCurrent()) {
            span.setAttribute("good", "job");
            childMethod();
        } catch (Throwable t) {
            span.setStatus(StatusCode.ERROR, "handle parent span error");
        } finally {
            span.end();
        }
    }

    public static void childMethod() {
        // Start a child span -- automatically linked to the parent through Context
        Span span = OpenTelemetrySupport.getTracer().spanBuilder("child span").startSpan();
        try (Scope scope = span.makeCurrent()) {
            span.setAttribute("hello", "world");
        } catch (Throwable t) {
            span.setStatus(StatusCode.ERROR, "handle child span error");
        } finally {
            span.end();
        }
    }

    public static void main(String[] args) {
        parentMethod();
    }
}

Step 4: Start the application and verify

Start the application, then open the Managed Service for OpenTelemetry console. On the Applications page, click your application name and confirm that traces appear.

Method 3: Combine the Java agent with the SDK

Use the agent for broad automatic coverage and the SDK for targeted custom spans. The agent auto-configures the SDK at startup through the opentelemetry-sdk-extension-autoconfigure dependency, so you do not need the OpenTelemetrySupport helper class from Method 2.

Step 1: Download the agent

Download the OpenTelemetry Java agent as described in Method 1, Step 1.

Step 2: Add Maven dependencies

In addition to the dependencies in Method 2, Step 1, add the following:

<dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-extension-annotations</artifactId>
</dependency>
<dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId>
    <version>1.23.0-alpha</version>
</dependency>
The opentelemetry-sdk-extension-autoconfigure dependency transfers agent settings to the SDK automatically, so you do not need to configure the exporter or resource attributes in code.

Full pom.xml dependencies

<dependencies>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.3</version>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-api</artifactId>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-sdk-trace</artifactId>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-extension-annotations</artifactId>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-exporter-otlp</artifactId>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-sdk</artifactId>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-semconv</artifactId>
        <version>1.30.0-alpha</version>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId>
        <version>1.23.0-alpha</version>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-bom</artifactId>
            <version>1.30.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Step 3: Get a tracer

Because the agent handles SDK initialization, get the global tracer directly:

OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
Tracer tracer = openTelemetry.getTracer("instrumentation-library-name", "1.0.0");

Step 4: Add custom instrumentation

Three techniques for adding instrumentation on top of the agent:

Technique 1: Add attributes to an auto-created span

Call Span.current() inside an already-instrumented method to attach business attributes:

@RequestMapping("/async")
public String async() {
    Span span = Span.current();
    span.setAttribute("user.id", "123456");
    userService.async();
    child("vip");
    return "async";
}

Technique 2: Use @WithSpan for annotation-based instrumentation

Annotate a method with @WithSpan to create a span automatically. Use @SpanAttribute to record parameters:

@WithSpan
private void child(@SpanAttribute("user.type") String userType) {
    System.out.println(userType);
    biz();
}

Technique 3: Create spans manually with a tracer

For full control, build spans with the tracer API. This example also propagates context into an async thread:

private void biz() {
    Tracer tracer = GlobalOpenTelemetry.get().getTracer("tracer");
    Span span = tracer.spanBuilder("biz (manual)")
        .setParent(Context.current().with(Span.current()))  // optional -- set automatically
        .startSpan();

    try (Scope scope = span.makeCurrent()) {
        span.setAttribute("biz-id", "111");

        // Propagate context into an async task
        es.submit(() -> {
            Span asyncSpan = tracer.spanBuilder("async")
                .setParent(Context.current().with(span))
                .startSpan();
            try {
                Thread.sleep(1000L);  // simulate async work
            } catch (Throwable e) {
                // handle error
            }
            asyncSpan.end();
        });

        Thread.sleep(1000);  // simulate business logic
    } catch (Throwable t) {
        span.setStatus(StatusCode.ERROR, "handle biz error");
    } finally {
        span.end();
    }
}

Full controller and service code

Controller (com.alibaba.arms.brightroar.console.controller):

package com.alibaba.arms.brightroar.console.controller;

import com.alibaba.arms.brightroar.console.service.UserService;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.extension.annotations.SpanAttribute;
import io.opentelemetry.extension.annotations.WithSpan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    private ExecutorService es = Executors.newFixedThreadPool(5);

    // Technique 1: Add attributes to an auto-created span
    @RequestMapping("/async")
    public String async() {
        System.out.println("UserController.async -- " + Thread.currentThread().getId());
        Span span = Span.current();
        span.setAttribute("user.id", "123456");
        userService.async();
        child("vip");
        return "async";
    }

    // Technique 2: Annotation-based instrumentation
    @WithSpan
    private void child(@SpanAttribute("user.type") String userType) {
        System.out.println(userType);
        biz();
    }

    // Technique 3: Manual span creation
    private void biz() {
        Tracer tracer = GlobalOpenTelemetry.get().getTracer("tracer");
        Span span = tracer.spanBuilder("biz (manual)")
            .setParent(Context.current().with(Span.current()))
            .startSpan();

        try (Scope scope = span.makeCurrent()) {
            span.setAttribute("biz-id", "111");

            es.submit(new Runnable() {
                @Override
                public void run() {
                    Span asyncSpan = tracer.spanBuilder("async")
                        .setParent(Context.current().with(span))
                        .startSpan();
                    try {
                        Thread.sleep(1000L); // simulate async work
                    } catch (Throwable e) {
                    }
                    asyncSpan.end();
                }
            });

            Thread.sleep(1000); // simulate business logic
            System.out.println("biz done");
            OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
            openTelemetry.getPropagators();
        } catch (Throwable t) {
            span.setStatus(StatusCode.ERROR, "handle biz error");
        } finally {
            span.end();
        }
    }

}

Service (com.alibaba.arms.brightroar.console.service):

package com.alibaba.arms.brightroar.console.service;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Async
    public void async() {
        System.out.println("UserService.async -- " + Thread.currentThread().getId());
        System.out.println("my name is async");
        System.out.println("UserService.async -- ");
    }
}

Step 5: Configure JVM parameters and start the application

java -javaagent:/path/to/opentelemetry-javaagent.jar \
  -Dotel.resource.attributes=service.name=<your-service-name> \
  -Dotel.exporter.otlp.headers=Authentication=<token> \
  -Dotel.exporter.otlp.endpoint=<endpoint> \
  -jar /path/to/your/app.jar

Example:

java -javaagent:/path/to/opentelemetry-javaagent.jar \
  -Dotel.resource.attributes=service.name=ot-java-agent-sample \
  -Dotel.exporter.otlp.headers=Authentication=b590xxxxuqs@3a75d95xxxxx9b_b59xxxxguqs@53dxxxx2afe8301 \
  -Dotel.exporter.otlp.endpoint=http://tracing-analysis-dc-bj:8090 \
  -jar /path/to/your/app.jar
To forward trace data through an OpenTelemetry Collector, remove -Dotel.exporter.otlp.headers=Authentication=<token> and set <endpoint> to the Collector address on your on-premises machine.

Open the Managed Service for OpenTelemetry console. On the Applications page, click your application name and confirm that traces appear.

Supported Java frameworks

The OpenTelemetry Java agent automatically instruments the following frameworks. For the complete and up-to-date list, see Supported libraries, frameworks, application servers, and JVMs.

Supported Java frameworks

FrameworkVersion
Akka Actors2.5 or later
Akka HTTP10.0 or later
Apache Axis21.6 or later
Apache Camel2.20 or later (excluding 3.x)
Apache DBCP2.0 or later
Apache CXF JAX-RS3.2 or later
Apache CXF JAX-WS3.0 or later
Apache Dubbo2.7 or later
Apache HttpAsyncClient4.1 or later
Apache HttpClient2.0 or later
Apache Kafka Producer/Consumer API0.11 or later
Apache Kafka Streams API0.11 or later
Apache MyFaces1.2 or later (excluding 3.x)
Apache Pulsar2.8 or later
Apache RocketMQ gRPC/Protobuf-based Client5.0 or later
Apache RocketMQ Remoting-based Client4.8 or later
Apache Struts 22.3 or later
Apache Tapestry5.4 or later
Apache Wicket8.0 or later
Armeria1.3 or later
AsyncHttpClient1.9 or later
AWS Lambda1.0 or later
AWS SDK1.11.x and 2.2 or later
Azure Core1.14 or later
Cassandra Driver3.0 or later
Couchbase Client2.0 or later and 3.1 or later
c3p00.9.2 or later
Dropwizard Metrics4.0 or later (disabled by default)
Dropwizard Views0.7 or later
Eclipse Grizzly2.3 or later
Eclipse Jersey2.0 or later (excluding 3.x)
Eclipse Jetty HTTP Client9.2 or later (excluding 10 or later)
Eclipse Metro2.2 or later
Eclipse Mojarra1.2 or later (excluding 3.x)
Elasticsearch API Client7.16 or later and 8.0 or later
Elasticsearch REST Client5.0 or later
Elasticsearch Transport Client5.0 or later
Finatra2.9 or later
Geode Client1.4 or later
Google HTTP Client1.19 or later
Grails3.0 or later
GraphQL Java12.0 or later
gRPC1.6 or later
Guava ListenableFuture10.0 or later
GWT2.0 or later
Hibernate3.3 or later
Hibernate Reactive1.0 or later
HikariCP3.0 or later
HttpURLConnectionJava 8 or later
Hystrix1.4 or later
Java ExecutorsJava 8 or later
Java Http ClientJava 11 or later
java.util.loggingJava 8 or later
Java PlatformJava 8 or later
JAX-RS0.5 or later
JAX-RS Client1.1 or later
JAX-WS2.0 or later (excluding 3.x)
JBoss Log Manager1.1 or later
JDBCJava 8 or later
Jedis1.4 or later
JMS1.1 or later
Jodd Http4.2 or later
JSP2.3 or later
Kotlin Coroutines1.0 or later
Ktor1.0 or later
Kubernetes Client7.0 or later
Lettuce4.0 or later
Log4j 11.2 or later
Log4j 22.11 or later
Logback1.0 or later
Micrometer1.5 or later
MongoDB Driver3.1 or later
Netty3.8 or later
OkHttp2.2 or later
Oracle UCP11.2 or later
OSHI5.3.1 or later
Play2.4 or later
Play WS1.0 or later
Quartz2.0 or later
R2DBC1.0 or later
RabbitMQ Client2.7 or later
Ratpack1.4 or later
Reactor3.1 or later
Reactor Netty0.9 or later
Rediscala1.8 or later
Redisson3.0 or later
RESTEasy3.0 or later
Restlet1.0 or later
RMIJava 8 or later
RxJava1.0 or later
Scala ForkJoinPool2.8 or later
Servlet2.2 or later
Spark Web Framework2.3 or later
Spring BootN/A
Spring Batch3.0 or later (excluding 5.0 or later)
Spring Cloud Gateway2.0 or later
Spring Data1.8 or later
Spring Integration4.1 or later (excluding 6.0 or later)
Spring JMS2.0 or later
Spring Kafka2.7 or later
Spring RabbitMQ1.0 or later
Spring Scheduling3.1 or later
Spring RestTemplate3.1 or later
Spring Web MVC3.1 or later
Spring Web Services2.0 or later
Spring WebFlux5.3 or later
Spymemcached2.12 or later
Tomcat JDBC Pool8.5 or later
Twilio6.6 or later (excluding 8.x)
Undertow1.4 or later
Vaadin14.2 or later
Vert.x Web3.0 or later
Vert.x HttpClient3.0 or later
Vert.x Kafka Client3.6 or later
Vert.x RxJava23.5 or later
Vert.x SQL Client4.0 or later
Vibur DBCP11.0 or later
ZIO2.0 or later