Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hide virtual field accessor interface methods from reflection #4390

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,18 @@ class ReflectionTest extends AgentInstrumentationSpecification {
}
}
methodFound == false

and:
def interfaceClass = TestClass.getInterfaces().find {
it.getName().contains("VirtualFieldAccessor\$")
}
interfaceClass != null
def interfaceMethodFound = false
for (Method method : interfaceClass.getDeclaredMethods()) {
if (method.getName().contains("__opentelemetry")) {
interfaceMethodFound = true
}
}
interfaceMethodFound == false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static Field[] filterFields(Class<?> containingClass, Field[] fields) {
}
List<Field> result = new ArrayList<>(fields.length);
for (Field field : fields) {
// FieldBackedProvider marks added fields as synthetic
// virtual fields are marked as synthetic
if (field.isSynthetic() && field.getName().startsWith("__opentelemetryVirtualField$")) {
continue;
}
Expand All @@ -32,13 +32,20 @@ public static Field[] filterFields(Class<?> containingClass, Field[] fields) {
}

public static Method[] filterMethods(Class<?> containingClass, Method[] methods) {
if (methods.length == 0
|| !VirtualFieldInstalledMarker.class.isAssignableFrom(containingClass)) {
if (methods.length == 0) {
return methods;
} else if (containingClass.isInterface()
&& containingClass.isSynthetic()
&& containingClass.getName().contains("VirtualFieldAccessor$")) {
// hide all methods from virtual field accessor interfaces
return new Method[0];
} else if (!VirtualFieldInstalledMarker.class.isAssignableFrom(containingClass)) {
// nothing to filter when class does not have any added virtual fields
return methods;
}
List<Method> result = new ArrayList<>(methods.length);
for (Method method : methods) {
// FieldBackedProvider marks added method as synthetic
// virtual field accessor methods are marked as synthetic
if (method.isSynthetic()
&& (method.getName().startsWith("get__opentelemetryVirtualField$")
|| method.getName().startsWith("set__opentelemetryVirtualField$"))) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,17 @@ private DynamicType.Unloaded<?> makeFieldAccessorInterface(
.makeInterface()
.merge(SyntheticState.SYNTHETIC)
.name(getFieldAccessorInterfaceName(typeName, fieldTypeName))
.defineMethod(getRealGetterName(typeName, fieldTypeName), fieldTypeDesc, Visibility.PUBLIC)
.defineMethod(
getRealGetterName(typeName, fieldTypeName),
fieldTypeDesc,
Visibility.PUBLIC,
SyntheticState.SYNTHETIC)
.withoutCode()
.defineMethod(
getRealSetterName(typeName, fieldTypeName), TypeDescription.VOID, Visibility.PUBLIC)
getRealSetterName(typeName, fieldTypeName),
TypeDescription.VOID,
Visibility.PUBLIC,
SyntheticState.SYNTHETIC)
.withParameter(fieldTypeDesc, "value")
.withoutCode()
.make();
Expand Down