55
66package io .opentelemetry .instrumentation .gradle ;
77
8- import static java .util .stream .Collectors .toList ;
9-
108import java .io .File ;
119import java .util .Arrays ;
12- import java .util .concurrent .Callable ;
1310import org .gradle .api .Plugin ;
1411import org .gradle .api .Project ;
15- import org .gradle .api .artifacts .Configuration ;
16- import org .gradle .api .file .DuplicatesStrategy ;
1712import org .gradle .api .plugins .JavaLibraryPlugin ;
18- import org .gradle .api .plugins .JavaPlugin ;
1913import org .gradle .api .tasks .Internal ;
20- import org .gradle .api .tasks .TaskProvider ;
2114import org .gradle .api .tasks .testing .Test ;
22- import org .gradle .jvm .tasks .Jar ;
2315import org .gradle .process .CommandLineArgumentProvider ;
2416
2517/**
2921// TODO(anuraaga): Migrate more build logic into this plugin to avoid having two places for it.
3022public 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}
0 commit comments