Revert okhttp library instrumentation back to using standard reflection to support Android usage (#3910)

* Revert back to using standard reflection to support Android usage

* Add a comment about not using MethodHandles
This commit is contained in:
John Watson 2021-08-23 18:58:43 -07:00 committed by GitHub
parent 3525733ea8
commit fa168268c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 18 additions and 21 deletions

View File

@ -9,9 +9,8 @@ import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.caching.Cache;
import java.io.IOException;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
@ -23,23 +22,21 @@ import org.checkerframework.checker.nullness.qual.Nullable;
class TracingCallFactory implements Call.Factory {
private static final Cache<Request, Context> contextsByRequest =
Cache.newBuilder().setWeakKeys().build();
@Nullable private static MethodHandle timeoutMethodHandle;
@Nullable private static MethodHandle cloneMethodHandle;
// We use old-school reflection here, rather than MethodHandles because Android doesn't support
// MethodHandles until API 26.
@Nullable private static Method timeoutMethod;
@Nullable private static Method cloneMethod;
static {
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
try {
MethodType methodType = MethodType.methodType(Timeout.class);
timeoutMethodHandle = lookup.findVirtual(Call.class, "timeout", methodType);
} catch (NoSuchMethodException | IllegalAccessException e) {
timeoutMethodHandle = null;
timeoutMethod = Call.class.getMethod("timeout");
} catch (NoSuchMethodException e) {
timeoutMethod = null;
}
try {
MethodType methodType = MethodType.methodType(Call.class);
cloneMethodHandle = lookup.findVirtual(Call.class, "clone", methodType);
} catch (NoSuchMethodException | IllegalAccessException e) {
cloneMethodHandle = null;
cloneMethod = Call.class.getDeclaredMethod("clone");
} catch (NoSuchMethodException e) {
cloneMethod = null;
}
}
@ -78,14 +75,14 @@ class TracingCallFactory implements Call.Factory {
@Override
public Call clone() throws CloneNotSupportedException {
if (cloneMethodHandle == null) {
if (cloneMethod == null) {
return (Call) super.clone();
}
try {
// we pull the current context here, because the cloning might be happening in a different
// context than the original call creation.
return new TracingCall((Call) cloneMethodHandle.invoke(delegate), Context.current());
} catch (Throwable e) {
return new TracingCall((Call) cloneMethod.invoke(delegate), Context.current());
} catch (IllegalAccessException | InvocationTargetException e) {
return (Call) super.clone();
}
}
@ -119,12 +116,12 @@ class TracingCallFactory implements Call.Factory {
// @Override method was introduced in 3.12
public Timeout timeout() {
if (timeoutMethodHandle == null) {
if (timeoutMethod == null) {
return Timeout.NONE;
}
try {
return (Timeout) timeoutMethodHandle.invoke(delegate);
} catch (Throwable e) {
return (Timeout) timeoutMethod.invoke(delegate);
} catch (IllegalAccessException | InvocationTargetException e) {
// do nothing...we're before 3.12, or something else has gone wrong that we can't do
// anything about.
return Timeout.NONE;