@@ -97,14 +97,13 @@ public static void enableClassInjection(Instrumentation inst) {
9797 try {
9898 InjectGlue injectGlue = new InjectGlue ();
9999 try {
100- // temporary transformation to install our glue to access ClassLoader. defineClass
100+ // temporary transformation to install our glue to access ' defineClass'
101101 inst .addTransformer (injectGlue , true );
102- inst .retransformClasses (ClassLoader .class );
103- ClassLoader cl = ClassLoader .getSystemClassLoader ();
104- classDefiner = (BiFunction ) cl .loadClass (DefineClassGlue .ID ).newInstance ();
102+ inst .retransformClasses (Class .class );
103+ classDefiner = (BiFunction ) Class .forName (DefineClassGlue .ID ).newInstance ();
105104 } finally {
106105 inst .removeTransformer (injectGlue );
107- inst .retransformClasses (ClassLoader .class );
106+ inst .retransformClasses (Class .class );
108107 }
109108 } catch (Throwable e ) {
110109 throw new UnsupportedOperationException ("Class injection not available" , e );
@@ -119,39 +118,37 @@ public byte[] transform(
119118 Class <?> classBeingRedefined ,
120119 ProtectionDomain protectionDomain ,
121120 byte [] bytecode ) {
122- if ("java/lang/ClassLoader " .equals (className )) {
121+ if ("java/lang/Class " .equals (className )) {
123122 ClassReader cr = new ClassReader (bytecode );
124123 ClassWriter cw = new ClassWriter (cr , 0 );
125- cr .accept (new ClassLoaderPatch (cw ), 0 );
124+ cr .accept (new ClassPatch (cw ), 0 );
126125 return cw .toByteArray ();
127126 } else {
128127 return null ;
129128 }
130129 }
131130 }
132131
133- static final class ClassLoaderPatch extends ClassVisitor {
134- ClassLoaderPatch (ClassVisitor cv ) {
132+ static final class ClassPatch extends ClassVisitor {
133+ ClassPatch (ClassVisitor cv ) {
135134 super (ASM9 , cv );
136135 }
137136
138137 @ Override
139138 public MethodVisitor visitMethod (
140139 int access , String name , String descriptor , String signature , String [] exceptions ) {
141140 MethodVisitor mv = cv .visitMethod (access , name , descriptor , signature , exceptions );
142- // hook into both forms of the 'loadClass' method to retrieve the injected glue
143- // custom system class-loaders will call one of them to fetch bootstrap classes
144- if ((access & ACC_STATIC ) == 0
145- && "loadClass" .equals (name )
146- && descriptor .startsWith ("(Ljava/lang/String;" )) {
147- return new LoadClassPatch (mv );
141+ if ((access & ACC_STATIC ) != 0
142+ && "forName" .equals (name )
143+ && "(Ljava/lang/String;)Ljava/lang/Class;" .equals (descriptor )) {
144+ return new ForNamePatch (mv );
148145 }
149146 return mv ;
150147 }
151148 }
152149
153- static final class LoadClassPatch extends MethodVisitor {
154- LoadClassPatch (MethodVisitor mv ) {
150+ static final class ForNamePatch extends MethodVisitor {
151+ ForNamePatch (MethodVisitor mv ) {
155152 super (ASM9 , mv );
156153 }
157154
@@ -161,9 +158,9 @@ public void visitCode() {
161158
162159 Label notDatadogGlueRequest = new Label ();
163160
164- // add branch at start of loadClass method to define our glue as a hidden/anonymous class
161+ // add branch at start of Class.forName method to define our glue as a hidden/anonymous class
165162 mv .visitLdcInsn (DefineClassGlue .ID );
166- mv .visitVarInsn (ALOAD , 1 );
163+ mv .visitVarInsn (ALOAD , 0 );
167164 mv .visitMethodInsn (
168165 INVOKEVIRTUAL , "java/lang/String" , "equals" , "(Ljava/lang/Object;)Z" , false );
169166 mv .visitJumpInsn (IFEQ , notDatadogGlueRequest );
@@ -241,7 +238,7 @@ public void visitCode() {
241238
242239 mv .visitInsn (ARETURN );
243240
244- // otherwise this is a standard load request, handle it as before
241+ // otherwise this is a standard Class.forName request, handle it as before
245242 mv .visitLabel (notDatadogGlueRequest );
246243 mv .visitFrame (F_SAME , 0 , null , 0 , null );
247244 }
0 commit comments