Skip to content

Commit 50c74a4

Browse files
authored
Inject defineClass glue by patching Class.forName (#27)
1 parent f319d27 commit 50c74a4

File tree

1 file changed

+17
-20
lines changed

1 file changed

+17
-20
lines changed

class-inject/src/main/java/datadog/instrument/classinject/ClassInjector.java

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)