2.2 KiB
DarkReflection
DarkReflection brings FULL reflection back to new java versions.
There are several strategies for different java versions, allowing for compatibility across all versions of OpenJDK from 8 to 22. (Other JDKs are likely but not tested to work.)
Strategies
Class access
Class access is how DR gets the fields, methods, and constructors of a class.
Basic uses the getDeclaredX() methods. This does not work in the most recent few versions.
NativeGet uses the underlying getDeclaredX0() methods. This is less performant, but works on all stable java versions. (Early access versions are to be tested soon.)
Field access
Field access is how DR reads and writes to/from fields that are private or final.
Basic uses the setAccessible(true) call.
Adapted uses the DarkAccessibleObject helper, which uses an unsafe to
change the accessible
field of the AccessibleObject. At first, this
tries to use getDeclaredField to obtain the field handle, then falls back
to a FakeAccessibleObject, which is a class with the same memory layout as
AccessibleObject, to get the field offset.
Unsafe completely bypasses the AccessibleObject part by using the unsafe on the field directly.
FieldByName access
GetDeclaredField uses the regular Field strategy by wrapping the name in the basic getDeclaredField().
DarkReflection uses the regular Field strategy, but obtains the field handle using the Class strategy instead.
Unsafe is currently unnecessary, and uses a hidden unsafe method to obtain the field offset directly from the name. Then, it uses the Unsafe Field strategy on that offset.
UnsafeCompat
DarkReflection also exposes a consistent unsafe API, that ports Java 8's
defineClass
method to newer versions, and backports & opens the hidden
objectFieldOffset(name) method.
As the unsafe API shifts further, more and more will be added to the UnsafeCompat API.
This is accessed through the UnsafeProvider.
Does this always work?
I treat any malfunction or absence of function as a bug, but I cannot guarantee reliability as this is simply a hobby project of mine.
Feel free to test this on as many java versions and runtimes as possible.