io.opentelemetry.javaagent.tooling.UnsafeInitializer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of opentelemetry-javaagent-tooling-java9 Show documentation
Show all versions of opentelemetry-javaagent-tooling-java9 Show documentation
Instrumentation of Java libraries using OpenTelemetry.
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.tooling;
import static java.util.logging.Level.WARNING;
import io.opentelemetry.javaagent.bootstrap.AgentClassLoader;
import java.lang.instrument.Instrumentation;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
public class UnsafeInitializer {
private static final Logger logger = Logger.getLogger(UnsafeInitializer.class.getName());
static void initialize(Instrumentation instrumentation, ClassLoader classLoader) {
initialize(instrumentation, classLoader, true);
}
private static void initialize(
Instrumentation instrumentation, ClassLoader classLoader, boolean testUnsafePresent) {
Class> unsafeClass;
try {
unsafeClass = Class.forName("jdk.internal.misc.Unsafe");
} catch (ClassNotFoundException exception) {
return;
}
Map> exports = new HashMap<>();
// expose jdk.internal.misc.Unsafe to our agent
// this is used to generate our replacement sun.misc.Unsafe and also by grpc/netty to call
// jdk.internal.misc.Unsafe.allocateUninitializedArray
exports.put(
unsafeClass.getPackage().getName(),
Collections.singleton(UnsafeInitializer.class.getModule()));
instrumentation.redefineModule(
unsafeClass.getModule(),
Collections.emptySet(),
exports,
Collections.emptyMap(),
Collections.emptySet(),
Collections.emptyMap());
if (testUnsafePresent && hasSunMiscUnsafe()) {
return;
}
if (!(classLoader instanceof AgentClassLoader)) {
// some tests don't pass AgentClassLoader, ignore them
return;
}
try {
SunMiscUnsafeGenerator.generateUnsafe(unsafeClass, (AgentClassLoader) classLoader);
} catch (Throwable throwable) {
logger.log(WARNING, "Unsafe generation failed", throwable);
}
}
private static boolean hasSunMiscUnsafe() {
try {
Class.forName("sun.misc.Unsafe");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
}