This commit is contained in:
parent
e50427340d
commit
70f165a858
1 changed files with 67 additions and 0 deletions
67
README.md
Normal file
67
README.md
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
# 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.
|
||||||
|
|
Loading…
Reference in a new issue