1111import de .thetaphi .forbiddenapis .SuppressForbidden ;
1212import java .io .File ;
1313import java .io .IOException ;
14- import java .lang .reflect .Field ;
15- import java .lang .reflect .Method ;
1614import java .net .MalformedURLException ;
1715import java .net .URL ;
1816import java .net .URLClassLoader ;
19- import java .util .Arrays ;
2017import java .util .HashSet ;
2118import java .util .Set ;
2219import java .util .TreeSet ;
@@ -29,16 +26,15 @@ public class BootstrapClasspathSetup implements LauncherSessionListener {
2926
3027 @ Override
3128 public void launcherSessionOpened (LauncherSession session ) {
32- // do nothing
29+ // this method is only needed to trigger this class' static initializer before JUnit does
30+ // classpath scanning
3331 }
3432
35- /**
36- * An exact copy of {@link datadog.trace.bootstrap.Constants#BOOTSTRAP_PACKAGE_PREFIXES}.
37- *
38- * <p>This list is needed to initialize the bootstrap classpath because Utils' static initializer
39- * references bootstrap classes (e.g. DatadogClassLoader).
40- */
41- public static final String [] BOOTSTRAP_PACKAGE_PREFIXES_COPY = {
33+ private static final String [] TEST_EXCLUDED_BOOTSTRAP_PACKAGE_PREFIXES = {
34+ "ch.qos.logback.classic.servlet" , // this draws javax.servlet deps that are not needed
35+ };
36+
37+ private static final String [] TEST_BOOTSTRAP_PREFIXES = {
4238 "datadog.slf4j" ,
4339 "datadog.context" ,
4440 "datadog.environment" ,
@@ -51,32 +47,14 @@ public void launcherSessionOpened(LauncherSession session) {
5147 "datadog.trace.instrumentation.api" ,
5248 "datadog.trace.logging" ,
5349 "datadog.trace.util" ,
50+ "org.slf4j" ,
51+ "ch.qos.logback" ,
5452 };
5553
56- private static final String [] TEST_EXCLUDED_BOOTSTRAP_PACKAGE_PREFIXES = {
57- "ch.qos.logback.classic.servlet" , // this draws javax.servlet deps that are not needed
58- };
59-
60- private static final String [] TEST_BOOTSTRAP_PREFIXES ;
61-
62- public static final ClassPath TEST_CLASSPATH ;
54+ public static final ClassPath TEST_CLASSPATH = computeTestClasspath ();
6355
6456 static {
6557 ByteBuddyAgent .install ();
66- final String [] testBS = {
67- "org.slf4j" , "ch.qos.logback" ,
68- };
69-
70- TEST_BOOTSTRAP_PREFIXES =
71- Arrays .copyOf (
72- BOOTSTRAP_PACKAGE_PREFIXES_COPY ,
73- BOOTSTRAP_PACKAGE_PREFIXES_COPY .length + testBS .length );
74- for (int i = 0 ; i < testBS .length ; ++i ) {
75- TEST_BOOTSTRAP_PREFIXES [i + BOOTSTRAP_PACKAGE_PREFIXES_COPY .length ] = testBS [i ];
76- }
77-
78- TEST_CLASSPATH = computeTestClasspath ();
79-
8058 setupBootstrapClasspath ();
8159 }
8260
@@ -116,41 +94,6 @@ private static ClassLoader buildJavaClassPathClassLoader() {
11694 return new URLClassLoader (urls .build ().toArray (new URL [0 ]), null );
11795 }
11896
119- public static void assertNoBootstrapClassesInTestClass (final Class <?> testClass ) {
120- for (final Field field : testClass .getDeclaredFields ()) {
121- assertNotBootstrapClass (testClass , field .getType ());
122- }
123- for (final Method method : testClass .getDeclaredMethods ()) {
124- assertNotBootstrapClass (testClass , method .getReturnType ());
125- for (final Class <?> paramType : method .getParameterTypes ()) {
126- assertNotBootstrapClass (testClass , paramType );
127- }
128- }
129- }
130-
131- private static void assertNotBootstrapClass (final Class <?> testClass , final Class <?> clazz ) {
132- if (!clazz .isPrimitive () && isBootstrapClass (clazz .getName ())) {
133- throw new IllegalStateException (
134- testClass .getName ()
135- + ": Bootstrap classes are not allowed in test class field or method signatures. Offending class: "
136- + clazz .getName ());
137- }
138- }
139-
140- private static boolean isBootstrapClass (final String name ) {
141- for (String prefix : TEST_BOOTSTRAP_PREFIXES ) {
142- if (name .startsWith (prefix )) {
143- for (String excluded : TEST_EXCLUDED_BOOTSTRAP_PACKAGE_PREFIXES ) {
144- if (name .startsWith (excluded )) {
145- return false ;
146- }
147- }
148- return true ;
149- }
150- }
151- return false ;
152- }
153-
15497 private static void setupBootstrapClasspath () {
15598 // Ensure there weren't any bootstrap classes loaded prematurely.
15699 Set <String > prematureBootstrapClasses = new TreeSet <>();
@@ -172,8 +115,6 @@ private static void setupBootstrapClasspath() {
172115 final File bootstrapJar = createBootstrapJar ();
173116 ByteBuddyAgent .getInstrumentation ()
174117 .appendToBootstrapClassLoaderSearch (new JarFile (bootstrapJar ));
175- // Utils cannot be referenced before this line, as its static initializers load bootstrap
176- // classes (for example, the bootstrap proxy).
177118 BootstrapProxy .addBootstrapResource (bootstrapJar .toURI ().toURL ());
178119 } catch (final IOException e ) {
179120 throw new RuntimeException (e );
@@ -192,4 +133,18 @@ private static File createBootstrapJar() throws IOException {
192133 SpockExtension .class .getClassLoader (), bootstrapClasses .toArray (new String [0 ]));
193134 return new File (jar .getFile ());
194135 }
136+
137+ public static boolean isBootstrapClass (final String name ) {
138+ for (String prefix : TEST_BOOTSTRAP_PREFIXES ) {
139+ if (name .startsWith (prefix )) {
140+ for (String excluded : TEST_EXCLUDED_BOOTSTRAP_PACKAGE_PREFIXES ) {
141+ if (name .startsWith (excluded )) {
142+ return false ;
143+ }
144+ }
145+ return true ;
146+ }
147+ }
148+ return false ;
149+ }
195150}
0 commit comments