GraalVM Native Image

OneAgent version 1.295+ Dynatrace version 1.295+

GraalVM Native Image is designed to achieve high performance when running applications written in Java and other languages by pre-compiling Java code into native images. AOT-compiled native images contain only the Java code required at runtime and exclude everything else from the libraries and frameworks.

Dynatrace provides end-to-end distributed tracing for your native Java applications pre-compiled as GraalVM Native Image running in virtualized, containerized, and K8s environments. Dynatrace automatically discovers your native Java apps' services and visualizes their dependencies from the website to containers, infrastructure, and the cloud. It diagnoses anomalies in real-time using AI and determines the root cause down to the broken code. Performance metrics give you insight into memory usage, garbage collection, and threads.

For the supported distributed tracing technologies, see Java Native Image.

Dynatrace GraalVM Native Image observability requires a Full-Stack Monitoring license.

Get started

The Dynatrace GraalVM Native Image module consists of a build-time module and a runtime module. The build-time module must be present during Native Image build-time. The runtime module must be present when the Native Image is executed to capture telemetry data.

  • Both modules must be of the same version for compatibility reasons.
  • No changes to your application code are required.

Download GraalVM Native Image module

Download the GraalVM Native Image module from Dynatrace OneAgent Deployment API for your target platform.

An example API call using curl:

curl -X GET "$DT_TENANT_URL/api/v1/deployment/installer/agent/$OS_TYPE/paas/latest?flavor=default&arch=$ARCH&bitness=64&include=java-graal-native&skipMetadata=true" -H "accept: application/octet-stream" -H "Authorization: Api-Token $DT_API_TOKEN" -o agent.zip

Replace $DT_TENANT_URL, $OS_TYPE, $ARCH, and $DT_API_TOKEN with your Dynatrace environment values.

  • $DT_TENANT_URL is your Dynatrace environment URL.
  • $OS_TYPE can be unix or windows.
  • $ARCH can be x86 or arm, while arm is only available for the OS type unix.
  • $DT_API_TOKEN is your access token with the PaaS integration - Installer download scope. To learn how to generate the token, see Generate access token.

Integrate Dynatrace in Maven project

To integrate Dynatrace in a Maven project:

  1. Add the following to your pom.xml file:

    <profile>
    <id>dynatrace-native</id>
    <build>
    <plugins>
    <plugin>
    <groupId>com.dynatrace.buildtools.graalnative</groupId>
    <artifactId>dynatrace-native-maven-plugin</artifactId>
    <version>1.0.0</version>
    <executions>
    <execution>
    <goals>
    <goal>setup-build-agent</goal>
    <goal>copy-runtime-agent</goal>
    </goals>
    </execution>
    </executions>
    <extensions>true</extensions>
    </plugin>
    </plugins>
    </build>
    <properties>
    <dynatrace.agent.zip>PATH_TO_DOWNLOADED_ZIP</dynatrace.agent.zip>
    </properties>
    </profile>

    Replace PATH_TO_DOWNLOADED_ZIP with the absolute or relative path to the downloaded ZIP file.

  2. Run mvnw package -Pnative -Pdynatrace-native. This will generate a Native Image, including Dynatrace. The native profile adds the Maven plugin for GraalVM Native image building.

    Typically, the resulting Native Image will be available in the target folder. Besides the Native Image, there will be a dynatrace folder. It is required for monitoring at runtime. If you want to run the Native Image on another machine, copy the dynatrace folder along with the Native Image.

Integrate Dynatrace in Gradle project

Prerequisites
  • Gradle 8.4+ runs on a supported JVM or Native Image of Java version 17+.
  • Gradle plugin org.graalvm.buildtools:native-gradle-plugin with version 0.10+ is applied to your project.

To integrate Dynatrace in a Gradle project:

  1. Add the following code to settings.gradle:

    pluginManagement {
    repositories {
    mavenCentral()
    }
    }
  2. Add the following code to build.gradle:

    plugins {
    id 'com.dynatrace.buildtools.graalnative' version '1.0.0'
    }
    dynatrace {
    agentZip = "PATH_TO_DOWNLOADED_ZIP"
    // example: agentZip = "./agent.zip"
    }

    Replace PATH_TO_DOWNLOADED_ZIP with the absolute or relative path to the downloaded ZIP file.

  3. Run gradlew dynatraceNativeCompile to generate a Native Image, including Dynatrace.

    Typically, the resulting Native Image is available in the folder build/native/nativeCompile. Besides the Native Image, the folder contains a dynatrace folder. It is required for monitoring at runtime. If you want to run the Native Image on another machine, copy the dynatrace folder along with the Native Image.

Activate Dynatrace observability

If you already have OneAgent installed or use Dynatrace Operator for Kubernetes, the Dynatrace connection details are automatically applied and GraalVM Native Image observability activated.

To activate Dynatrace observability at runtime, define your Dynatrace connection details using the environment variables DT_TENANT, DT_TENANTTOKEN, and DT_CONNECTION_POINT. An example for Dynatrace SaaS:

export DT_TENANT=$DT_TENANT_ID
export DT_TENANTTOKEN=$DT_TENANTTOKEN
export DT_CONNECTION_POINT=$DT_CONNECTION_POINT
./$YOUR_APP_NAME

Replace $DT_TENANT_ID, $DT_TENANTTOKEN, and $DT_CONNECTION_POINT with your Dynatrace connection details. Replace $YOUR_APP_NAME with your application name.

You can retrieve your connection details via View connectivity information for OneAgent API call. You need the following fields of the response:

  • tenantUUID for $DT_TENANT_ID
  • tenantToken for $DT_TENANTTOKEN
  • communicationEndpoints for $DT_CONNECTION_POINT

Optional settings

Maven plugin

The Maven plugin is configured via the dynatrace-native profile in the pom.xml file. For example:

<properties>
<dynatrace.agent.zip>PATH_TO_DOWNLOADED_ZIP</dynatrace.agent.zip>
<dynatrace.agent.options>loglevelcon=info</dynatrace.agent.options>
</properties>

You can configure the following properties:

  • dynatrace.agent.zip sets the absolute or relative path to the downloaded ZIP file.
  • dynatrace.agent.options defines the options for the Dynatrace build-time module.

The following dynatrace.agent.options are available:

  • loglevelcon sets the console logging level. Possible values: off (default), severe, warning, and info.
  • agentconfigpath sets the absolute path to a JSON configuration file (see the next section).

Gradle plugin

The Gradle plugin is configured via a dynatrace block in build.gradle. For example:

dynatrace {
agentZip = "PATH_TO_DOWNLOADED_ZIP"
agentOptions = "loglevelcon=info"
}

You can configure the following properties:

  • agentZip sets the absolute or relative path to the downloaded ZIP file.
  • agentOptions defines the options for the Dynatrace build-time module.

The following agentOptions are available:

  • loglevelcon sets the console logging level. Possible values: off (default), severe, warning, and info.
  • agentconfigpath sets the absolute path to a JSON configuration file (see the next section).

JSON configuration file

The Dynatrace build-time module is preconfigured with recommended settings. If needed, you can override the defaults via a JSON configuration file at build time. For example:

{
"enabledSensors": [
"servlet"
]
}

The following enabledSensors (instrumentation points) are available:

  • servlet: Incoming HTTP requests via Servlet API
  • netty: Incoming HTTP requests via Netty
  • httpclient: Outgoing HTTP requests
  • threading: Context propagation for threads and executors
  • mongo: MongoDB database calls

Remove a sensor from the enabledSensors list to deactivate it.

Known limitations

This is expected to be no longer necessary in GraalVM versions 17.0.12+, 21.0.4+, and 22.0.2+.

If you are using Spring RestTemplate and get unconnected traces, please try the following workaround.

Maven projects

Configure in your pom.xml file:

<jvmArgs>
<arg>--add-opens=java.base/sun.net.www.protocol.http=ALL-UNNAMED</arg>
<arg>--add-opens=java.base/java.net=ALL-UNNAMED</arg>
<arg>--add-exports=java.base/sun.net.www=ALL-UNNAMED</arg>
</jvmArgs>

For reference, see Maven plugin for GraalVM Native Image building.

Gradle projects

Configure in your build.gradle file:

graalvmNative {
binaries {
main {
jvmArgs.addAll(
'--add-opens', 'java.base/sun.net.www.protocol.http=ALL-UNNAMED',
'--add-opens', 'java.base/java.net=ALL-UNNAMED',
'--add-exports', 'java.base/sun.net.www=ALL-UNNAMED'
)
}
}
}