Skip to content

Commit

Permalink
Trying to extract codegen plugin (#3521)
Browse files Browse the repository at this point in the history
* Muzzle code generation moved to a separate plugin
* Restored old MuzzleCodeGenerationPlugin to use until the new one is published
* The simplest dependency management possible

Co-authored-by: Anuraag Agrawal <aanuraag@amazon.co.jp>
  • Loading branch information
iNikem and Anuraag Agrawal authored Jul 14, 2021
1 parent 229d8ad commit cbfd7e1
Show file tree
Hide file tree
Showing 31 changed files with 1,859 additions and 14 deletions.
3 changes: 3 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ dependencies {
implementation(gradleApi())
implementation(localGroovy())

//TODO start using this when separate codegen plugin is published
// implementation("io.opentelemetry.instrumentation.gradle:opentelemetry-codegen:1.4.0-alpha-SNAPSHOT")

implementation("org.eclipse.aether:aether-connector-basic:1.1.0")
implementation("org.eclipse.aether:aether-transport-http:1.1.0")
implementation("org.apache.maven:maven-aether-provider:3.3.9")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ plugins {
`java-library`
}

//TODO remove this when separate codegen plugin is published
/**
* Starting from version 1.10.15, ByteBuddy gradle plugin transformation task autoconfiguration is
* hardcoded to be applied to javaCompile task. This causes the dependencies to be resolved during
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id("io.opentelemetry.instrumentation.javaagent-testing")
id("io.opentelemetry.instrumentation.muzzle-check")
id("io.opentelemetry.instrumentation.javaagent-codegen")
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ dependencies {

testImplementation("io.opentelemetry.javaagent:opentelemetry-testing-common")

add("codegen", "io.opentelemetry.javaagent:opentelemetry-javaagent-bootstrap")
add("codegen", "io.opentelemetry.javaagent:opentelemetry-javaagent-tooling")
add("codegen", "io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api")
}

val testInstrumentation by configurations.creating {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import java.net.URLClassLoader
* by taking a delegate class name and class path as arguments and loading the plugin class from the
* provided classloader when the plugin is instantiated.
*/
//TODO remove together with io.opentelemetry.instrumentation.javaagent-codegen.gradle
class ClasspathByteBuddyPlugin(
classPath: Iterable<File>, sourceDirectory: File, className: String
) : Plugin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import java.io.File
* exposed to Gradle via [Classpath] annotation, which cannot be done if it is returned by
* [Transformation.getArguments].
*/
//TODO remove together with io.opentelemetry.instrumentation.javaagent-codegen.gradle
class ClasspathTransformation(
@get:Classpath val classpath: Iterable<File>,
@get:Input val pluginClassName: String
Expand Down
1 change: 1 addition & 0 deletions buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ configurations.configureEach {
substitute(module("io.opentelemetry.javaagent:opentelemetry-javaagent-tooling")).using(project(":javaagent-tooling"))
substitute(module("io.opentelemetry.javaagent:opentelemetry-agent-for-testing")).using(project(":testing:agent-for-testing"))
substitute(module("io.opentelemetry.javaagent:opentelemetry-testing-common")).using(project(":testing-common"))
substitute(module("io.opentelemetry.javaagent:opentelemetry-muzzle")).using(project(":muzzle"))
}

// The above substitutions ensure dependencies managed by this BOM for external projects refer to this repo's projects here.
Expand Down
3 changes: 3 additions & 0 deletions buildSrc/src/main/kotlin/otel.spotless-conventions.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ spotless {
// ktfmt() // only supports 4 space indentation
ktlint().userData(mapOf("indent_size" to "2", "continuation_indent_size" to "2"))
licenseHeaderFile(rootProject.file("gradle/enforcement/spotless.license.java"), "(package|import|public)")
targetExclude(
"src/main/kotlin/io.opentelemetry.instrumentation.javaagent-codegen.gradle.kts",
"build/**")
}
format("misc") {
// not using "**/..." to help keep spotless fast
Expand Down
2 changes: 1 addition & 1 deletion dependencyManagement/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ val DEPENDENCY_SETS = listOf(
"net.bytebuddy",
// When updating, also update buildSrc/build.gradle.kts
"1.11.2",
listOf("byte-buddy", "byte-buddy-agent")
listOf("byte-buddy", "byte-buddy-agent", "byte-buddy-gradle-plugin")
),
DependencySet(
"org.mockito",
Expand Down
2 changes: 1 addition & 1 deletion docs/contributing/muzzle.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ and is shared between all type instrumentations. The bytecode of this method (ba
ByteBuddy plugin using an ASM code visitor.

The source code of the compile-time plugin is located in the `javaagent-tooling` module,
package `io.opentelemetry.javaagent.tooling.muzzle.collector`.
package `io.opentelemetry.javaagent.muzzle.generation.collector`.

### Runtime reference matching

Expand Down
2 changes: 2 additions & 0 deletions examples/extension/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ plugins {
See https://imperceptiblethoughts.com/shadow/ for more details about Shadow plugin.
*/
id "com.github.johnrengelman.shadow" version "6.1.0"

id "io.opentelemetry.instrumentation.javaagent-codegen" version "0.1.0"
}

group 'io.opentelemetry.example'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
7 changes: 7 additions & 0 deletions examples/extension/settings.gradle
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
pluginManagement {
repositories {
gradlePluginPortal()
mavenLocal()
}
}

rootProject.name = 'opentelemetry-java-instrumentation-extension-demo'
27 changes: 27 additions & 0 deletions gradle-plugins/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
plugins {
`kotlin-dsl`
`maven-publish`

id("com.gradle.plugin-publish")
}

group = "io.opentelemetry.instrumentation.gradle"
version = "0.1.0"

repositories {
mavenCentral()
mavenLocal()
}

dependencies {
implementation("com.google.guava:guava:30.1.1-jre")
implementation("net.bytebuddy:byte-buddy-gradle-plugin:1.11.2")
implementation("io.opentelemetry.javaagent:opentelemetry-muzzle:1.4.0-alpha-SNAPSHOT")
implementation("io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api:1.4.0-alpha-SNAPSHOT")
}

pluginBundle {
website = "https://opentelemetry.io"
vcsUrl = "https://github.com/open-telemetry/opentelemetry-java-instrumentation"
tags = listOf("opentelemetry", "instrumentation")
}
6 changes: 6 additions & 0 deletions gradle-plugins/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pluginManagement {
plugins {
id("com.gradle.plugin-publish") version "0.15.0"
id("org.jetbrains.kotlin.jvm") version "1.5.10"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.muzzle.generation;

import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import java.util.HashSet;
import java.util.Set;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;

final class AdviceClassNameCollector implements TypeTransformer {
private final Set<String> adviceClassNames = new HashSet<>();

@Override
public void applyAdviceToMethod(
ElementMatcher<? super MethodDescription> methodMatcher, String adviceClassName) {
adviceClassNames.add(adviceClassName);
}

@Override
public void applyTransformer(AgentBuilder.Transformer transformer) {}

Set<String> getAdviceClassNames() {
return adviceClassNames;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.muzzle.generation;

import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
import java.net.URLClassLoader;
import net.bytebuddy.build.Plugin;
import net.bytebuddy.description.type.TypeDefinition;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.ClassFileLocator;
import net.bytebuddy.dynamic.DynamicType;

/**
* This class is a ByteBuddy build plugin that is responsible for generating actual implementation
* of some {@link InstrumentationModule} methods. Auto-generated methods have the word "muzzle" in
* their names.
*
* <p>This class is used in the gradle build scripts, referenced by each instrumentation module.
*/
public final class MuzzleCodeGenerationPlugin implements Plugin {

private static final TypeDescription instrumentationModuleType =
new TypeDescription.ForLoadedType(InstrumentationModule.class);

private final URLClassLoader classLoader;

public MuzzleCodeGenerationPlugin(URLClassLoader classLoader) {
this.classLoader = classLoader;
}

@Override
public boolean matches(TypeDescription target) {
if (target.isAbstract()) {
return false;
}
boolean isInstrumentationModule = false;
TypeDefinition instrumentation = target.getSuperClass();
while (instrumentation != null) {
if (instrumentation.equals(instrumentationModuleType)) {
isInstrumentationModule = true;
break;
}
instrumentation = instrumentation.getSuperClass();
}
return isInstrumentationModule;
}

@Override
public DynamicType.Builder<?> apply(
DynamicType.Builder<?> builder,
TypeDescription typeDescription,
ClassFileLocator classFileLocator) {
return builder.visit(new MuzzleCodeGenerator(classLoader));
}

@Override
public void close() {}
}
Loading

0 comments on commit cbfd7e1

Please sign in to comment.