On 31/03/2017 14:46, Matej Novotny wrote:
Hello,
I work on Weld, context dependency injection framework.
Long story short - we need to generate proxies for classes - bytecode which we then
"register" with the class loader using java.lang.ClassLoader#defineClass.
Obviously, for this you need reflections - to load java.lang.ClassLoader, then
to load the method itself, and most importantly, to make the method accessible
cause it's `protected`.
In JDK 9, this blows up as soon as you try to make the method accessible
(invocation of setAccessible).
Fair enough, but what is the "legitimate" alternative?
I know I can --add-opens / --add-opens / --permit-illegal-access
But all those just bypass the checks and don't really solve it. I am looking
for an intended way to do such stuff.
I am pretty sure there are many frameworks which need to do this in one way or
the other.
So far I have found workarounds which involve using `sun.misc.Unsafe` because
there (for some reason) you are allowed to invoke setAccessible().
Is this the official intended backdoor? Because it sure does not look any
safer/cleaner solution than the original one...
As Claes pointed out, look at Lookup.defineClass. It shouldn't be too
hard to imagine a future update of the CDI spec where there a select
variant that includes a Lookup to the target class with the @Inject
annotation. When using Weld outside of a container then I think there is
main code that obtains the WeldContainer and selects the types, that
might be a suitable place to extend to provide the Lookup to the library.
MethodHandles.privateLookupIn might also be useful to know about, esp.
starting out when you don't want to make API changes and where the
user's code is on the class path or in open modules.
-Alan