setAccessible() alternative with Jigsaw
Alan.Bateman at oracle.com
Fri Mar 31 14:28:34 UTC 2017
On 31/03/2017 14:46, Matej Novotny wrote:
> 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.
More information about the jigsaw-dev