javagradlejavaagentsopen-telemetry

Manage javaagent dependencies in a Java project built with Gradle


For systems that require a javaagent (say, OpenTelemetry) the docs often start with "download the agent JAR from this URL and add it to your command line". In a world where library dependencies are handled quite well using Maven Central, with stable versioning etc., the "download a JAR" approach seems primitive and insecure by comparison.

What is the best practice for acquiring javaagent libraries in a project built with Gradle? Is "download this jar" really the current state of the art?

I'm specifically interested in OpenTelemetry right now. If there's an answer (eg. a Gradle plugin) that only works for OpenTelemetry, I'm all ears.


Solution

  • From what I have done research, there is one gradle plugin available specifically for attaching a maven dependency as javaagent.

    Quoting from plugin github repository:

    This Gradle plugin tightly integrates with the Gradle application plugin to make instrumenting your application build by Gradle easy! Simply register the javaagent-application plugin and then specify the javaagent you would like to attach in the dependencies block

    Example usage with otel java agent can found in the same repository here

    plugins {
        id("com.ryandens.javaagent.example.java-application-conventions")
        id("com.ryandens.javaagent-otel-modification")
        id("com.ryandens.javaagent-application")
    }
    
    dependencies {
      otel("io.opentelemetry.javaagent:opentelemetry-javaagent:1.13.1")
      otelExtension("io.opentelemetry.contrib:opentelemetry-samplers:1.13.0-alpha")
      otelInstrumentation(project(":custom-instrumentation", "shadow"))
    }
    
    application {
        // Define the main class for the application.
        mainClass.set("com.ryandens.javaagent.example.App")
        applicationDefaultJvmArgs = listOf("-Dotel.javaagent.debug=true", "-Dotel.metrics.exporter=none")
    }
    
    /*
      see https://github.com/johnrengelman/shadow/issues/713
      Currently, tasks that consume the output of the extendedAgent shadowJar task need to be made aware of
      the implicit dependency (https://docs.gradle.org/7.4.2/userguide/validation_problems.html#implicit_dependency)
      due to an issue with the shadowJar plugin
    */
    setOf(tasks.distTar, tasks.distZip).forEach {
      it.configure {
        dependsOn(tasks.extendedAgent)
      }
    }