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