Skip to content

Commit a31111f

Browse files
committed
make ClassLoaderMap not use unsafe
1 parent 79b53bd commit a31111f

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/util/ClassLoaderMap.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.opentelemetry.javaagent.tooling.util;
77

88
import io.opentelemetry.instrumentation.api.internal.cache.Cache;
9+
import io.opentelemetry.javaagent.tooling.HelperInjector;
910
import java.lang.ref.WeakReference;
1011
import java.lang.reflect.Field;
1112
import java.util.Collections;
@@ -15,7 +16,6 @@
1516
import net.bytebuddy.ByteBuddy;
1617
import net.bytebuddy.description.modifier.Ownership;
1718
import net.bytebuddy.description.modifier.Visibility;
18-
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
1919

2020
class ClassLoaderMap {
2121
private static final Cache<ClassLoader, WeakReference<Map<Object, Object>>> data = Cache.weak();
@@ -51,20 +51,24 @@ private static Map<Object, Object> getClassLoaderData(
5151

5252
@SuppressWarnings("unchecked")
5353
private static Map<Object, Object> createMap(ClassLoader classLoader) {
54+
String className =
55+
"io.opentelemetry.javaagent.ClassLoaderData$$"
56+
+ Integer.toHexString(System.identityHashCode(classLoader));
5457
// generate a class with a single static field named "data" and define it in the given class
5558
// loader
56-
Class<?> clazz =
59+
byte[] bytes =
5760
new ByteBuddy()
5861
.subclass(Object.class)
59-
.name(
60-
"io.opentelemetry.javaagent.ClassLoaderData$$"
61-
+ Integer.toHexString(System.identityHashCode(classLoader)))
62+
.name(className)
6263
.defineField("data", Object.class, Ownership.STATIC, Visibility.PUBLIC)
6364
.make()
64-
.load(classLoader, ClassLoadingStrategy.Default.INJECTION.allowExistingTypes())
65-
.getLoaded();
65+
.getBytes();
66+
HelperInjector.injectHelperClasses(
67+
classLoader, Collections.singletonMap(className, () -> bytes));
6668
Map<Object, Object> map;
6769
try {
70+
Class<?> clazz = Class.forName(className, false, classLoader);
71+
6872
Field field = clazz.getField("data");
6973
synchronized (classLoader) {
7074
map = (Map<Object, Object>) field.get(classLoader);

muzzle/src/main/java/io/opentelemetry/javaagent/tooling/HelperInjector.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,23 @@ private void injectHelperClasses(
297297
}
298298
}
299299

300+
public static void injectHelperClasses(
301+
ClassLoader classLoader, Map<String, Supplier<byte[]>> classNameToBytes) {
302+
if (isBootClassLoader(classLoader)) {
303+
throw new UnsupportedOperationException("boot loader not supported");
304+
}
305+
if (classNameToBytes.isEmpty()) {
306+
return;
307+
}
308+
309+
Map<String, HelperClass> map =
310+
helperClasses.computeIfAbsent(classLoader, (unused) -> new ConcurrentHashMap<>());
311+
for (Map.Entry<String, Supplier<byte[]>> entry : classNameToBytes.entrySet()) {
312+
HelperClass injector = new HelperClass(entry.getValue());
313+
map.put(entry.getKey(), injector);
314+
}
315+
}
316+
300317
private static Map<String, byte[]> resolve(Map<String, Supplier<byte[]>> classes) {
301318
Map<String, byte[]> result = new LinkedHashMap<>();
302319
for (Map.Entry<String, Supplier<byte[]>> entry : classes.entrySet()) {

0 commit comments

Comments
 (0)