Migrate Java OpenTelemetry APM

Overview

The OpenTelemetry Java agent uses bytecode injection to automatically instrument any Java 8+ application at startup — no code changes required. For manual instrumentation, the Java SDK provides APIs to create and manage spans directly. This page covers installing the agent, setting up instrumentation, and configuring the OTLP exporter to send traces to Kloudfuse.

Install

Download the Java agent JAR and attach it to your application via JAVA_TOOL_OPTIONS:

curl -L -O https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
export JAVA_TOOL_OPTIONS="-javaagent:/path/to/opentelemetry-javaagent.jar"

Set Up Instrumentation

For manual instrumentation, add the OpenTelemetry API dependency and create spans in your code:

<dependency>
  <groupId>io.opentelemetry</groupId>
  <artifactId>opentelemetry-api</artifactId>
</dependency>
xml

Use the global tracer provider to get a tracer and create spans:

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;

Tracer tracer = GlobalOpenTelemetry.getTracer("my-service");

Span span = tracer.spanBuilder("my-operation").startSpan();
try (var scope = span.makeCurrent()) {
    // your work here
} finally {
    span.end();
}
java

The Java agent initializes GlobalOpenTelemetry automatically at startup, so you do not need to initialize the SDK manually when using the agent.

For full SDK initialization (without the agent), follow the OpenTelemetry documentation on Instrumentation.

Send to Kloudfuse

Configure the OTLP exporter by setting the following environment variables before starting your application:

export OTEL_EXPORTER_OTLP_ENDPOINT="https://<kloudfuse-hostname>/ingester/otlp"   (1)
export OTEL_EXPORTER_OTLP_HEADERS="Kf-Api-Key=<api-key>"                          (2)
export OTEL_SERVICE_NAME="my-service"
export OTEL_RESOURCE_ATTRIBUTES="deployment.environment=production"
1 Replace <kloudfuse-hostname> with your Kloudfuse cluster hostname.
2 Replace <api-key> with your Kloudfuse API key.

Instrumentation Libraries

The Java agent automatically instruments many popular libraries and frameworks at startup. Review the full list of Supported Libraries and Frameworks.

Troubleshooting

No Traces Appear

Verify JAVA_TOOL_OPTIONS is set and points to the correct JAR path before the JVM starts. If your application is started by a wrapper script or container entrypoint, confirm the variable is exported in that environment and not just the parent shell.

Check the application startup logs for a line similar to:

[otel.javaagent] ... OpenTelemetry Java agent x.x.x loaded

If this line is absent, the agent is not attaching.

JAVA_TOOL_OPTIONS Not Picked Up

Some application servers and process managers override JAVA_TOOL_OPTIONS or set their own JVM flags that prevent the agent from loading. In those cases, pass the -javaagent flag directly via the server’s JVM options configuration, for example JAVA_OPTS or CATALINA_OPTS:

export JAVA_OPTS="-javaagent:/path/to/opentelemetry-javaagent.jar"

Custom Spans Are Missing

GlobalOpenTelemetry.getTracer() returns a no-op tracer if called before the agent initializes. Ensure any code that calls GlobalOpenTelemetry.getTracer() runs after the application fully starts, not during static initialization blocks.