|
| 1 | +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar |
| 2 | + |
| 3 | +plugins { |
| 4 | + `java-library` |
| 5 | + id("elastic-otel.java-conventions") |
| 6 | + id("io.opentelemetry.instrumentation.muzzle-generation") |
| 7 | + id("io.opentelemetry.instrumentation.muzzle-check") |
| 8 | +} |
| 9 | + |
| 10 | +// Other instrumentations to include for testing |
| 11 | +val testInstrumentation: Configuration by configurations.creating { |
| 12 | + isCanBeConsumed = false |
| 13 | +} |
| 14 | +val agentForTesting: Configuration by configurations.creating { |
| 15 | + isCanBeConsumed = false |
| 16 | +} |
| 17 | + |
| 18 | +//https://github.com/gradle/gradle/issues/15383 |
| 19 | +val catalog = extensions.getByType<VersionCatalogsExtension>().named("catalog") |
| 20 | +dependencies { |
| 21 | + agentForTesting(platform(catalog.findLibrary("opentelemetryInstrumentationAlphaBom").get())) |
| 22 | + agentForTesting("io.opentelemetry.javaagent:opentelemetry-agent-for-testing") |
| 23 | + |
| 24 | + compileOnly("io.opentelemetry:opentelemetry-sdk") |
| 25 | + compileOnly("io.opentelemetry.instrumentation:opentelemetry-instrumentation-api") |
| 26 | + compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api") |
| 27 | + |
| 28 | + testImplementation("io.opentelemetry.javaagent:opentelemetry-testing-common") |
| 29 | + testImplementation("io.opentelemetry:opentelemetry-sdk-testing") |
| 30 | + |
| 31 | + val agentVersion = catalog.findVersion("opentelemetryJavaagentAlpha").get() |
| 32 | + add("codegen", "io.opentelemetry.javaagent:opentelemetry-javaagent-tooling:${agentVersion}") |
| 33 | + add("muzzleBootstrap", "io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations-support:${agentVersion}") |
| 34 | + add("muzzleTooling", "io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api:${agentVersion}") |
| 35 | + add("muzzleTooling", "io.opentelemetry.javaagent:opentelemetry-javaagent-tooling:${agentVersion}") |
| 36 | +} |
| 37 | + |
| 38 | +fun relocatePackages( shadowJar : ShadowJar) { |
| 39 | + // rewrite dependencies calling Logger.getLogger |
| 40 | + shadowJar.relocate("java.util.logging.Logger", "io.opentelemetry.javaagent.bootstrap.PatchLogger") |
| 41 | + |
| 42 | + // prevents conflict with library instrumentation, since these classes live in the bootstrap class loader |
| 43 | + shadowJar.relocate("io.opentelemetry.instrumentation", "io.opentelemetry.javaagent.shaded.instrumentation") { |
| 44 | + // Exclude resource providers since they live in the agent class loader |
| 45 | + exclude("io.opentelemetry.instrumentation.resources.*") |
| 46 | + exclude("io.opentelemetry.instrumentation.spring.resources.*") |
| 47 | + } |
| 48 | + |
| 49 | + // relocate(OpenTelemetry API) since these classes live in the bootstrap class loader |
| 50 | + shadowJar.relocate("io.opentelemetry.api", "io.opentelemetry.javaagent.shaded.io.opentelemetry.api") |
| 51 | + shadowJar.relocate("io.opentelemetry.semconv", "io.opentelemetry.javaagent.shaded.io.opentelemetry.semconv") |
| 52 | + shadowJar.relocate("io.opentelemetry.context", "io.opentelemetry.javaagent.shaded.io.opentelemetry.context") |
| 53 | + shadowJar.relocate("io.opentelemetry.extension.incubator", "io.opentelemetry.javaagent.shaded.io.opentelemetry.extension.incubator") |
| 54 | + |
| 55 | + // relocate the OpenTelemetry extensions that are used by instrumentation modules |
| 56 | + // these extensions live in the AgentClassLoader, and are injected into the user's class loader |
| 57 | + // by the instrumentation modules that use them |
| 58 | + shadowJar.relocate("io.opentelemetry.extension.aws", "io.opentelemetry.javaagent.shaded.io.opentelemetry.extension.aws") |
| 59 | + shadowJar.relocate("io.opentelemetry.extension.kotlin", "io.opentelemetry.javaagent.shaded.io.opentelemetry.extension.kotlin") |
| 60 | +} |
| 61 | + |
| 62 | +tasks { |
| 63 | + shadowJar { |
| 64 | + configurations = listOf(project.configurations.runtimeClasspath.get(), testInstrumentation) |
| 65 | + mergeServiceFiles() |
| 66 | + |
| 67 | + archiveFileName.set("agent-testing.jar") |
| 68 | + relocatePackages(this) |
| 69 | + } |
| 70 | +} |
| 71 | + |
| 72 | +tasks.withType<Test>().configureEach { |
| 73 | + dependsOn(tasks.shadowJar, agentForTesting) |
| 74 | + |
| 75 | + jvmArgs( |
| 76 | + "-Dotel.javaagent.debug=true", |
| 77 | + "-javaagent:${agentForTesting.files.first().absolutePath}", |
| 78 | + // loads the given just jar, but in contrast to external extensions doesn't perform runtime shading |
| 79 | + // instead the instrumentations are expected to be correctly shaded already in the jar |
| 80 | + // Also the classes end up in the agent classloader instead of the extension loader |
| 81 | + "-Dotel.javaagent.experimental.initializer.jar=${tasks.shadowJar.get().archiveFile.get().asFile.absolutePath}", |
| 82 | + "-Dotel.javaagent.testing.additional-library-ignores.enabled=false", |
| 83 | + "-Dotel.javaagent.testing.fail-on-context-leak=true", |
| 84 | + "-Dotel.javaagent.testing.transform-safe-logging.enabled=true", |
| 85 | + "-Dotel.metrics.exporter=otlp" |
| 86 | + ) |
| 87 | + |
| 88 | + // The sources are packaged into the testing jar so we need to make sure to exclude from the test |
| 89 | + // classpath, which automatically inherits them, to ensure our shaded versions are used. |
| 90 | + classpath = classpath.filter { |
| 91 | + return@filter !(it == file("${layout.buildDirectory.get()}/resources/main") || it == file("${layout.buildDirectory.get()}/classes/java/main")) |
| 92 | + } |
| 93 | +} |
0 commit comments