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.
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.
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.
The reason you have to drop the PRIVATE mode is because it is expected
to be used in the future. JDK-8171335  and JEP 181  provide some
context as how this could evolve.
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.
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).
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).
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?
3) All in all the changes carried along a lot of complexity compared to plain
We need to create A LOT of Lookups (might present performance overhead, haven't
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.
Multi-release JARs (JEP 238 ) and the ability to compile to older
releases (JEP 247 ) might be useful here (you might know about these
Another nasty thing is that the code of course needs to work with both, JDK 9
While it isn't impossible, it will add a not-so-nice reflection magic layer to