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

Remove virtual field interfaces from reflection results #4722

Merged
merged 2 commits into from
Nov 29, 2021

Conversation

laurit
Copy link
Contributor

@laurit laurit commented Nov 26, 2021

Resolves #4370
I initially planned to use asm SerialVersionUIDAdder to add serialVersionUID field to serializable classes that don't declare it. This is needed to make sure that instrumented version of class has the same serialVersionUID as uninstrumented version. This approach failed with one of spring-batch tests because inside spring there is code that copies instances of an internal spring class via reflection and fails because it can't write to serialVersionUID which is a static final field. We can't use the same reflection filtering code as we use for fields & methods added by virtual field implementetion because that filtering completely removes these members from reflection results. For serialVersionUID we'd need it to be visible from getDeclaredField, so that ObjectStreamClass can read it, and hidden from getDeclaredFields, so that code that isn't explicitly looking for it wouldn't stumble upon it. Instead of attempting to remove serialVersionUID from getDeclaredFields I chose to remove interfaces added by virtual field implementation from the result of getInterfaces. This makes the default serialVersionUID computation algorithm return the correct result on instrumented classes and there is no need to precompute serialVersionUID for them.

Copy link
Contributor

@iNikem iNikem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope you know what you are doing :D Instrumenting java.lang.Class seems scary

@trask
Copy link
Member

trask commented Nov 28, 2021

@laurit do you think we could get rid of these interfaces and use method handles to access the generated methods?

@laurit
Copy link
Contributor Author

laurit commented Nov 29, 2021

@trask Firstly we would need to figure out a new way to detect whether virtual fields have been added to a class which is currently handled by testing for VirtualFieldInstalledMarker interface or virtual field accessor interface. This could be implemented using a map with class name+class loader as key, but as the whole point of virtual fields is to avoid using maps we'd probably need to come up with something else. If we somehow end up using method handles then one thing to consider is that we can't always initialize them in static initializer because presence of <clinit> method also changes the default serial version uid.

@@ -36,6 +38,7 @@ private ReflectionHelper() {}
return methods;
} else if (containingClass.isInterface()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, I'll open an issue to try this 👍

Copy link
Member

@trask trask left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

presence of <clinit> method also changes the default serial version uid.

😭

@@ -36,6 +38,7 @@ private ReflectionHelper() {}
return methods;
} else if (containingClass.isInterface()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, I'll open an issue to try this 👍

@trask trask merged commit 92f83f1 into open-telemetry:main Nov 29, 2021
@laurit laurit deleted the virtual-field-interfaces branch November 29, 2021 20:10
RashmiRam pushed a commit to RashmiRam/opentelemetry-auto-instr-java that referenced this pull request May 23, 2022
…ry#4722)

* Remove virtual field interfaces from reflection results

* fix java8 and openj9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Compute serialVersionUID for Serializable classes that don't have one and use VirtualField
4 participants