io.opentelemetry.javaagent.bootstrap.IndyBootstrapDispatcher Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of opentelemetry-javaagent-bootstrap Show documentation
Show all versions of opentelemetry-javaagent-bootstrap Show documentation
Instrumentation of Java libraries using OpenTelemetry.
The newest version!
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.bootstrap;
import java.lang.invoke.CallSite;
import java.lang.invoke.ConstantCallSite;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Array;
/**
* Contains the bootstrap method for initializing invokedynamic callsites which are added via agent
* instrumentation.
*/
public class IndyBootstrapDispatcher {
private static volatile MethodHandle bootstrap;
private IndyBootstrapDispatcher() {}
/**
* Initialized the invokedynamic bootstrapping method to which this class will delegate.
*
* @param bootstrapMethod the method to delegate to. Must have the same type as {@link
* #bootstrap}.
*/
public static void init(MethodHandle bootstrapMethod) {
bootstrap = bootstrapMethod;
}
public static CallSite bootstrap(
MethodHandles.Lookup lookup,
String adviceMethodName,
MethodType adviceMethodType,
Object... args) {
CallSite callSite = null;
if (bootstrap != null) {
try {
callSite = (CallSite) bootstrap.invoke(lookup, adviceMethodName, adviceMethodType, args);
} catch (Throwable e) {
ExceptionLogger.logSuppressedError("Error bootstrapping indy instruction", e);
}
}
if (callSite == null) {
// The MethodHandle pointing to the Advice could not be created for some reason,
// fallback to a Noop MethodHandle to not crash the application
MethodHandle noop = generateNoopMethodHandle(adviceMethodType);
callSite = new ConstantCallSite(noop);
}
return callSite;
}
public static MethodHandle generateNoopMethodHandle(MethodType methodType) {
Class> returnType = methodType.returnType();
MethodHandle noopNoArg;
if (returnType == void.class) {
noopNoArg =
MethodHandles.constant(Void.class, null).asType(MethodType.methodType(void.class));
} else {
noopNoArg = MethodHandles.constant(returnType, getDefaultValue(returnType));
}
return MethodHandles.dropArguments(noopNoArg, 0, methodType.parameterList());
}
private static Object getDefaultValue(Class> classOrPrimitive) {
if (classOrPrimitive.isPrimitive()) {
// arrays of primitives are initialized with the correct primitive default value (e.g. 0 for
// int.class)
// we use this fact to generate the correct default value reflectively
return Array.get(Array.newInstance(classOrPrimitive, 1), 0);
} else {
return null; // null is the default value for reference types
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy