Thanks Remi, I strongly agree. In fact, with the ability to implement multiple methods in an invoke proxy (presumably through passing a list of name and handle pairs, and the impl method descriptors are stored in handles' method types), we can allow implementing any number of interfaces (even ones with language-wise conflicting methods like String getValue() and Long getValue()) and perform better initialization-time verifications (compared to invocation handlers, where users often forget to implement object methods and the proxy breaks only when it is sent into a hash set)
My current vision is a proxy factory method that takes a list of interfaces and a list of method implementations, each represented by a pair of name and method handle. However, I don't know well about native compilation, so I wonder if this structure would serve native optimization well, or if it has any other drawbacks. Please enlighten me. On Wed, Aug 25, 2021 at 5:22 AM Remi Forax <fo...@univ-mlv.fr> wrote: > > ----- Original Message ----- > > From: "-" <liangchenb...@gmail.com> > > To: "Brian Goetz" <brian.go...@oracle.com>, "core-libs-dev" > > <core-libs-dev@openjdk.java.net> > > Sent: Lundi 23 Août 2021 08:34:17 > > Subject: Re: Implementing MethodHandleProxies#asInterfaceInstance with > > hidden classes > > > Thanks for the quick reply! > > > > The main drawback, API wise, with LMF is that it does not accept > > non-direct method handles [1], while the MHP is able accept any method > > handle, such as native ones from JEP 389 [2]. LMF also lacks the > > ability to restore a method handle from a wrapper instance. Using LMF > > also requires user discretion on which methods to implement, and the > > lookup's required privileges may change too. In general, MHP would be > > more runtime-oriented and transient compared to LMF. > > > > I am inclined toward a separate bytecode generation implementation for > > the improved MHP asInterfaceInstance, somewhat similar to what's in > > JEP 416's implementation [3]. The extra bridges for all compatible > > methods, accessors to backing method handle/interface, potential to > > expand to abstract classes, different hidden class modes would reduce > > the commonalities between the two implementations and make > > refactorings on LMF to support these MHP functionalities costly. > > In my opinion, what is missing is a java.lang.invoke.Proxy, the equivalent of > java.lang.reflect.Proxy but using defineHiddenClass + a bootstrap method + > method handles instead of the InvocationHandler + j.l.r.Method. With that, > implementing java.lang.invoke.MethodHandleProxies on top of of > java.lang.invoke.Proxy is just a matter of wiring. > > As you said, there is a need for a more dynamic version of the > LambdaMetafactory. > I believe it should work with any interfaces not only functional interfaces. > This would avoid statically typed langages like Kotlin or Scala, or injection > frameworks like Weld, Spring or Guice to generate a lot of proxy classes and > it should be straightforward enough so static compilers like graal native > image or Android d8 can generate the proxy classes at compile time to support > "native" compilation (the same way lambdas are currently supported). > So we get best of both worlds, efficient dynamic proxies at runtime AND > supports of "native" compilation. > > Rémi > > > > > [1] > > https://github.com/openjdk/jdk/blob/b690f29699180149d33b6a83de10697790587a87/src/java.base/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java#L141 > > [2] https://openjdk.java.net/jeps/389#The-C-linker > > [3] > > https://github.com/openjdk/jdk/blob/cff856f9df89293cbc8f2f1e977148cd6ece4f85/src/java.base/share/classes/jdk/internal/reflect/ClassByteBuilder.java > > > > > > On Sun, Aug 22, 2021 at 9:26 PM Brian Goetz <brian.go...@oracle.com> wrote: > >> > >> This was an early attempt at the functionality provided by > >> LambdaMetafactory. > >> It could probably be reimplemented on top of that, but probably could be > >> deprecated in favor of LMF as well. > >> > >> Sent from my iPad > >> > >> > On Aug 22, 2021, at 10:08 PM, liangchenb...@gmail.com wrote: > >> > > >> > Currently, java.lang.invoke.MethodHandleProxies#asInterfaceInstance [1] > >> > is > >> > implemented with java.lang.reflect.Proxy. After looking at its public > >> > API, > >> > including Javadoc, it seems that MethodHandleProxies would benefit from a > >> > hidden class implementation without changing its public API definition > >> > (including Javadocs). > >> > > >> > Recently, there is JEP 416 [2] for reimplementing reflection based on > >> > method handles. This implementation utilizes hidden classes with method > >> > handles passed in classdata and retrieved to condy, which allows generic > >> > method handles (beyond regular constable ones) to be optimized in method > >> > calls. Similarly, for MethodHandleProxies, hidden classes allow the > >> > implementations to detach from classloaders and be freely recyclable; > >> > they > >> > can use class data to store the adapted method handles (which can > >> > significantly speed up invocations); and it can allow it to support > >> > implementing single-abstract-method abstract classes in the future (as > >> > discussed in its Javadoc) as well, with only minor tweaks. > >> > > >> > Does this sound feasible? I want to ensure it is a good idea before any > >> > implementation is attempted. If there is any issue with this vision, > >> > please > >> > don't hesitate to point it out. Feel free to comment, too! If this looks > >> > good, I hope an issue can be created for it. > >> > > >> > Best > >> > > >> > [1] > >> > https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/invoke/MethodHandleProxies.html > > > > [2] https://openjdk.java.net/jeps/416