DarkReflection/README.md
TudbuT 70f165a858
All checks were successful
/ Build & Publish (push) Successful in 1m17s
add readme
2024-08-11 13:32:15 +02:00

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.