setAccessible() alternative with Jigsaw - feedback on Lookup

Alan Bateman Alan.Bateman at oracle.com
Thu Apr 20 08:52:04 UTC 2017


On 20/04/2017 07:43, Matej Novotny wrote:

> So I did some hacking and tried to make Weld use MethodHandles.Lookup and here is a bit of a feedback for you.
> But first of all, thanks for your quick advice on how to approach this.
Thank you for writing down your experiences.

>
>
> So, how did Lookup work for us?
>
> 1) privateLookupIn + drop private mode
> This was the way to go, as the bean classes can be anywhere (in classes not openly accessible to us, especially if we consider modules).
> BTW I am not sure about the purpose of the private mode as you always need to drop it to be able to use lookup.
This should work fine for existing bean classes as presumably they are 
in the class path or at least not in modules that are strongly 
encapsulated. In the future then if the bean classes are compiled and 
deployed as modules then the owner of the module will have to open the 
packages to at least the library that wants to reflect deeply.

The reason you have to drop the PRIVATE mode is because it is expected 
to be used in the future. JDK-8171335 [1] and JEP 181 [2] provide some 
context as how this could evolve.

>
> 2) Lookup approach carries along the need to pass the reference to the base lookup class at all times.
> This is kind of weird  because in some (not-so-rare) cases, we need to create "artificial packages" in which we place proxy classes. For instance when we create a proxy for Interger, Map, Principal,...
> Ofc we cannot place in into java.* packages, so we create our own. For this to work with Lookup, we need to have that package created ahead of time and have a reference to some "dummy" useless class inside to be able to do the lookup.
> Or is there a way to define a whole new (open by default) package where we could place it using Lookup? Having the "dummy" package/class just to use Lookup is lame and very error prone (I can think of several ways to break the proxy creation even now).
What is the defining loader of the proxy class that you spin for types 
such as java.lang.Integer? If it's your class loader implementation then 
you can invoke its defineClass method to define the class, your don't 
need a Lookup to an existing class for that scenario.

If you are looking to define a class in a new runtime package and the 
class loader that is not your implementation then you are out of luck. 
Lookup is designed for doing computations in the context of an existing 
class. There is a note in the archives here from John Rose about 
extending the lookup API for cases like this but it would come with a 
lot of complexity. Also there isn't any notion of adding a package to a 
named module at this time. When java.lang.reflect.Proxy spins proxy 
classes then it doesn't add packages to named modules, it instead spins 
the proxy classes into its own module (something you could do too, 
assuming the classes that you are proxying are accessible).

>
> 3) All in all the changes carried along a lot of complexity compared to plain old ClassLoader.defineClass
> We need to create A LOT of Lookups (might present performance overhead, haven't tested yet).
> Extra care needs to be given to the packages for Lookup not to blow up while we in fact don't really care where the proxy lands as long as it is usable.
Can you expand on the "don't really care" comment? Do you mean that you 
don't care about either the defining loader or runtime package?

>
>
> Another nasty thing is that the code of course needs to work with both, JDK 9 and 8.
> While it isn't impossible, it will add a not-so-nice reflection magic layer to the mix.
>
Multi-release JARs (JEP 238 [3]) and the ability to compile to older 
releases (JEP 247 [4]) might be useful here (you might know about these 
features already).

-Alan.

[1] https://bugs.openjdk.java.net/browse/JDK-8171335
[2] http://openjdk.java.net/jeps/181
[3] http://openjdk.java.net/jeps/238
[4] http://openjdk.java.net/jeps/247


More information about the jigsaw-dev mailing list