Skip to content

Commit 0d716d2

Browse files
authored
Bump OpenTelemetry to 0.11.0 (#143)
* Bump OTEL to 0.11.0 Signed-off-by: Pavol Loffay <[email protected]> * bump BB Signed-off-by: Pavol Loffay <[email protected]>
1 parent c4f281b commit 0d716d2

File tree

32 files changed

+418
-299
lines changed

32 files changed

+418
-299
lines changed

buildSrc/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ dependencies {
3535
implementation("org.ow2.asm", "asm", "7.0-beta")
3636
implementation("org.ow2.asm", "asm-tree", "7.0-beta")
3737
implementation("org.apache.httpcomponents:httpclient:4.5.10")
38+
implementation("net.bytebuddy:byte-buddy-gradle-plugin:1.10.18")
3839

3940
testImplementation("org.spockframework", "spock-core", "1.3-groovy-2.5")
4041
testImplementation("org.codehaus.groovy", "groovy-all", "2.5.8")

buildSrc/src/main/groovy/MuzzlePlugin.groovy

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class MuzzlePlugin implements Plugin<Project> {
7676
ClassLoader userCL = createCompileDepsClassLoader(project, bootstrapProject)
7777
ClassLoader instrumentationCL = createInstrumentationClassloader(project, toolingProject)
7878
Method assertionMethod = instrumentationCL.loadClass('io.opentelemetry.javaagent.tooling.muzzle.matcher.MuzzleGradlePluginUtil')
79-
.getMethod('assertInstrumentationMuzzled', ClassLoader.class, ClassLoader.class, boolean.class)
79+
.getMethod('assertInstrumentationMuzzled', ClassLoader.class, ClassLoader.class, boolean.class)
8080
assertionMethod.invoke(null, instrumentationCL, userCL, true)
8181
}
8282
println "Muzzle executing for $project"
@@ -88,7 +88,7 @@ class MuzzlePlugin implements Plugin<Project> {
8888
doLast {
8989
ClassLoader instrumentationCL = createInstrumentationClassloader(project, toolingProject)
9090
Method assertionMethod = instrumentationCL.loadClass('io.opentelemetry.javaagent.tooling.muzzle.matcher.MuzzleGradlePluginUtil')
91-
.getMethod('printMuzzleReferences', ClassLoader.class)
91+
.getMethod('printMuzzleReferences', ClassLoader.class)
9292
assertionMethod.invoke(null, instrumentationCL)
9393
}
9494
}
@@ -311,17 +311,17 @@ class MuzzlePlugin implements Plugin<Project> {
311311
}
312312

313313
def draftVersion = versionString.contains("rc") ||
314-
versionString.contains(".cr") ||
315-
versionString.contains("alpha") ||
316-
versionString.contains("beta") ||
317-
versionString.contains("-b") ||
318-
versionString.contains(".m") ||
319-
versionString.contains("-m") ||
320-
versionString.contains("-dev") ||
321-
versionString.contains("-ea") ||
322-
versionString.contains("-atlassian-") ||
323-
versionString.contains("public_draft") ||
324-
versionString.matches(GIT_SHA_PATTERN)
314+
versionString.contains(".cr") ||
315+
versionString.contains("alpha") ||
316+
versionString.contains("beta") ||
317+
versionString.contains("-b") ||
318+
versionString.contains(".m") ||
319+
versionString.contains("-m") ||
320+
versionString.contains("-dev") ||
321+
versionString.contains("-ea") ||
322+
versionString.contains("-atlassian-") ||
323+
versionString.contains("public_draft") ||
324+
versionString.matches(GIT_SHA_PATTERN)
325325

326326
return !draftVersion
327327
}
@@ -382,7 +382,7 @@ class MuzzlePlugin implements Plugin<Project> {
382382
try {
383383
// find all instrumenters, get muzzle, and assert
384384
Method assertionMethod = instrumentationCL.loadClass('io.opentelemetry.javaagent.tooling.muzzle.matcher.MuzzleGradlePluginUtil')
385-
.getMethod('assertInstrumentationMuzzled', ClassLoader.class, ClassLoader.class, boolean.class)
385+
.getMethod('assertInstrumentationMuzzled', ClassLoader.class, ClassLoader.class, boolean.class)
386386
assertionMethod.invoke(null, instrumentationCL, userCL, muzzleDirective.assertPass)
387387
} finally {
388388
Thread.currentThread().contextClassLoader = ccl

buildSrc/src/main/java/io/opentelemetry/instrumentation/gradle/AutoInstrumentationPlugin.java

Lines changed: 8 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,13 @@
55

66
package io.opentelemetry.instrumentation.gradle;
77

8-
import static java.util.stream.Collectors.toList;
9-
108
import java.io.File;
119
import java.util.Arrays;
12-
import java.util.concurrent.Callable;
1310
import org.gradle.api.Plugin;
1411
import org.gradle.api.Project;
15-
import org.gradle.api.artifacts.Configuration;
16-
import org.gradle.api.file.DuplicatesStrategy;
1712
import org.gradle.api.plugins.JavaLibraryPlugin;
18-
import org.gradle.api.plugins.JavaPlugin;
1913
import org.gradle.api.tasks.Internal;
20-
import org.gradle.api.tasks.TaskProvider;
2114
import org.gradle.api.tasks.testing.Test;
22-
import org.gradle.jvm.tasks.Jar;
2315
import org.gradle.process.CommandLineArgumentProvider;
2416

2517
/**
@@ -29,106 +21,22 @@
2921
// TODO(anuraaga): Migrate more build logic into this plugin to avoid having two places for it.
3022
public class AutoInstrumentationPlugin implements Plugin<Project> {
3123

32-
/**
33-
* An exact copy of {@code
34-
* io.opentelemetry.javaagent.tooling.Constants#BOOTSTRAP_PACKAGE_PREFIXES}. We can't reference it
35-
* directly since this file needs to be compiled before the other packages.
36-
*/
37-
public static final String[] BOOTSTRAP_PACKAGE_PREFIXES_COPY = {
38-
"io.opentelemetry.javaagent.common.exec",
39-
"io.opentelemetry.javaagent.slf4j",
40-
"io.opentelemetry.javaagent.bootstrap",
41-
"io.opentelemetry.javaagent.shaded",
42-
"io.opentelemetry.javaagent.instrumentation.api",
43-
};
44-
45-
// Aditional classes we need only for tests and aren't shared with the agent business logic.
46-
private static final String[] TEST_BOOTSTRAP_PREFIXES;
47-
48-
static {
49-
String[] testBS = {
50-
"io.opentelemetry.instrumentation.api",
51-
"io.opentelemetry.api", // OpenTelemetry API
52-
"io.opentelemetry.context", // OpenTelemetry API
53-
"org.slf4j",
54-
"ch.qos.logback",
55-
// Tomcat's servlet classes must be on boostrap
56-
// when running tomcat test
57-
"javax.servlet.ServletContainerInitializer",
58-
"javax.servlet.ServletContext"
59-
};
60-
TEST_BOOTSTRAP_PREFIXES =
61-
Arrays.copyOf(
62-
BOOTSTRAP_PACKAGE_PREFIXES_COPY,
63-
BOOTSTRAP_PACKAGE_PREFIXES_COPY.length + testBS.length);
64-
System.arraycopy(
65-
testBS, 0, TEST_BOOTSTRAP_PREFIXES, BOOTSTRAP_PACKAGE_PREFIXES_COPY.length, testBS.length);
66-
for (int i = 0; i < TEST_BOOTSTRAP_PREFIXES.length; i++) {
67-
TEST_BOOTSTRAP_PREFIXES[i] = TEST_BOOTSTRAP_PREFIXES[i].replace('.', '/');
68-
}
69-
}
70-
7124
@Override
7225
public void apply(Project project) {
7326
project.getPlugins().apply(JavaLibraryPlugin.class);
74-
7527
project
7628
.getTasks()
7729
.withType(
7830
Test.class,
7931
task -> {
80-
TaskProvider<Jar> bootstrapJar =
81-
project.getTasks().register(task.getName() + "BootstrapJar", Jar.class);
82-
83-
Configuration testClasspath =
84-
project.getConfigurations().findByName(task.getName() + "RuntimeClasspath");
85-
if (testClasspath == null) {
86-
// Same classpath as default test task
87-
testClasspath =
88-
project
89-
.getConfigurations()
90-
.findByName(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME);
91-
}
92-
93-
String bootstrapJarName = task.getName() + "-bootstrap.jar";
94-
95-
Configuration testClasspath0 = testClasspath;
96-
bootstrapJar.configure(
97-
jar -> {
98-
jar.dependsOn(testClasspath0.getBuildDependencies());
99-
jar.getArchiveFileName().set(bootstrapJarName);
100-
jar.setIncludeEmptyDirs(false);
101-
// Classpath is ordered in priority, but later writes into the JAR would take
102-
// priority, so we exclude the later ones (we need this to make sure logback is
103-
// picked up).
104-
jar.setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE);
105-
jar.from(
106-
project.files(
107-
// Needs to be a Callable so it's executed lazily at runtime, instead of
108-
// configuration time where the classpath may still be getting built up.
109-
(Callable<?>)
110-
() ->
111-
testClasspath0.resolve().stream()
112-
.filter(
113-
file ->
114-
!file.isDirectory()
115-
&& file.getName().endsWith(".jar"))
116-
.map(project::zipTree)
117-
.collect(toList())));
118-
119-
jar.eachFile(
120-
file -> {
121-
if (!isBootstrapClass(file.getPath())) {
122-
file.exclude();
123-
}
124-
});
125-
});
126-
127-
task.dependsOn(bootstrapJar);
128-
task.getJvmArgumentProviders()
129-
.add(
130-
new InstrumentationTestArgs(
131-
new File(project.getBuildDir(), "libs/" + bootstrapJarName)));
32+
task.dependsOn(":testing-bootstrap:shadowJar");
33+
File testingBootstrapJar =
34+
new File(
35+
project.project(":testing-bootstrap").getBuildDir(),
36+
"libs/testing-bootstrap.jar");
37+
// Make sure tests get rerun if the contents of the testing-bootstrap.jar change
38+
task.getInputs().property("testing-bootstrap-jar", testingBootstrapJar);
39+
task.getJvmArgumentProviders().add(new InstrumentationTestArgs(testingBootstrapJar));
13240
});
13341
}
13442

@@ -150,13 +58,4 @@ public Iterable<String> asArguments() {
15058
"-Xbootclasspath/a:" + bootstrapJar.getAbsolutePath(), "-Dnet.bytebuddy.raw=true");
15159
}
15260
}
153-
154-
private static boolean isBootstrapClass(String filePath) {
155-
for (String testBootstrapPrefix : TEST_BOOTSTRAP_PREFIXES) {
156-
if (filePath.startsWith(testBootstrapPrefix)) {
157-
return true;
158-
}
159-
}
160-
return false;
161-
}
16261
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.gradle.bytebuddy;
7+
8+
import java.io.File;
9+
import java.util.Arrays;
10+
import java.util.List;
11+
import net.bytebuddy.build.gradle.ByteBuddySimpleTask;
12+
import net.bytebuddy.build.gradle.Transformation;
13+
import org.gradle.api.Project;
14+
import org.gradle.api.Task;
15+
import org.gradle.api.tasks.SourceSet;
16+
import org.gradle.api.tasks.compile.AbstractCompile;
17+
18+
/**
19+
* Starting from version 1.10.15, ByteBuddy gradle plugin transformation task autoconfiguration is
20+
* hardcoded to be applied to javaCompile task. This causes the dependencies to be resolved during
21+
* an afterEvaluate that runs before any afterEvaluate specified in the build script, which in turn
22+
* makes it impossible to add dependencies in afterEvaluate. Additionally the autoconfiguration will
23+
* attempt to scan the entire project for tasks which depend on the compile task, to make each task
24+
* that depends on compile also depend on the transformation task. This is an extremely inefficient
25+
* operation in this project to the point of causing a stack overflow in some environments.
26+
*
27+
* <p>To avoid all the issues with autoconfiguration, this class manually configures the ByteBuddy
28+
* transformation task. This also allows it to be applied to source languages other than Java. The
29+
* transformation task is configured to run between the compile and the classes tasks, assuming no
30+
* other task depends directly on the compile task, but instead other tasks depend on classes task.
31+
* Contrary to how the ByteBuddy plugin worked in versions up to 1.10.14, this changes the compile
32+
* task output directory, as starting from 1.10.15, the plugin does not allow the source and target
33+
* directories to be the same. The transformation task then writes to the original output directory
34+
* of the compile task.
35+
*/
36+
public class ByteBuddyPluginConfigurator {
37+
private static final List<String> LANGUAGES = Arrays.asList("java", "scala", "kotlin");
38+
39+
private final Project project;
40+
private final SourceSet sourceSet;
41+
private final String pluginClassName;
42+
private final Iterable<File> inputClasspath;
43+
44+
public ByteBuddyPluginConfigurator(
45+
Project project, SourceSet sourceSet, String pluginClassName, Iterable<File> inputClasspath) {
46+
this.project = project;
47+
this.sourceSet = sourceSet;
48+
this.pluginClassName = pluginClassName;
49+
this.inputClasspath = inputClasspath;
50+
}
51+
52+
public void configure() {
53+
String taskName = getTaskName();
54+
Task byteBuddyTask = project.getTasks().create(taskName);
55+
56+
for (String language : LANGUAGES) {
57+
AbstractCompile compile = getCompileTask(language);
58+
59+
if (compile != null) {
60+
Task languageTask = createLanguageTask(compile, taskName + language);
61+
byteBuddyTask.dependsOn(languageTask);
62+
}
63+
}
64+
65+
project.getTasks().getByName(sourceSet.getClassesTaskName()).dependsOn(byteBuddyTask);
66+
}
67+
68+
private Task createLanguageTask(AbstractCompile compileTask, String name) {
69+
ByteBuddySimpleTask task = project.getTasks().create(name, ByteBuddySimpleTask.class);
70+
task.setGroup("Byte Buddy");
71+
task.getOutputs().cacheIf(unused -> true);
72+
73+
File classesDirectory = compileTask.getDestinationDir();
74+
File rawClassesDirectory =
75+
new File(classesDirectory.getParent(), classesDirectory.getName() + "raw")
76+
.getAbsoluteFile();
77+
78+
task.dependsOn(compileTask);
79+
compileTask.setDestinationDir(rawClassesDirectory);
80+
81+
task.setSource(rawClassesDirectory);
82+
task.setTarget(classesDirectory);
83+
task.setClassPath(compileTask.getClasspath());
84+
85+
task.dependsOn(compileTask);
86+
87+
task.getTransformations().add(createTransformation(inputClasspath, pluginClassName));
88+
return task;
89+
}
90+
91+
private AbstractCompile getCompileTask(String language) {
92+
Task task = project.getTasks().findByName(sourceSet.getCompileTaskName(language));
93+
94+
if (task instanceof AbstractCompile) {
95+
AbstractCompile compile = (AbstractCompile) task;
96+
97+
if (!compile.getSource().isEmpty()) {
98+
return compile;
99+
}
100+
}
101+
102+
return null;
103+
}
104+
105+
private String getTaskName() {
106+
if (SourceSet.MAIN_SOURCE_SET_NAME.equals(sourceSet.getName())) {
107+
return "byteBuddy";
108+
} else {
109+
return sourceSet.getName() + "ByteBuddy";
110+
}
111+
}
112+
113+
private static Transformation createTransformation(
114+
Iterable<File> classPath, String pluginClassName) {
115+
Transformation transformation = new ClasspathTransformation(classPath, pluginClassName);
116+
transformation.setPlugin(ClasspathByteBuddyPlugin.class);
117+
return transformation;
118+
}
119+
}

0 commit comments

Comments
 (0)