Le jeu. 9 août 2018 à 10:49, <h2gr@abula.org> a écrit :
Why would anyone subclass Closure? Isn't there enough trouble to be
found elsewhere?

It is common in java code integrating with groovy code.
 

H2


Den 2018-08-08 20:05, skrev Jochen Theodorou:
> Hi all,
>
> during JCrete I was playing around with removing some of those
> setAccessible calls and found one quite problematic case.
>
> AS many here know we have some implementation details for our
> Closures, one of them is the following: You can subclass Closure and
> declare a doCall method which will the drive part of the logic
> (accepted arguments and such) In fact all of our Closures usages in
> Groovy currently end up in one or more doCall methods.
>
> Now the problem is, if you declare an anonymous inner class of a
> Closure with a doCall method in Java (yes, we do this in our
> codebase), then it is quite difficult to give the runtime (or DGM)
> access to this method.
>
> First I thought the super class Closure could have access if the
> method is at least public, but AICs are not public, which
> automatically restricts access to methods declared in them, not
> available otherwise.
>
> I then started to play around with the AIC exhibiting a method handle
> to Closure to allow Closure to call the doCall method using the
> MethodHandles API. But this will of course add several lines of code
> to the subclass, that where not needed before.
>
> And then not to forget about our plan to make our Closures into
> something more similar to lambdas in Java.
>
> That did make me think...
>
> (1) maybe Closure should have a factory method that allows a
> MethodHandle (or more than one) to be properly registered (ClassValue
> I am thinking here), to allow us to call doCall from call
>
> (2) maybe the method should be more convenient and take a Lookup
> object and method name instead for the user
>
> (3) even better would be to be able to use a Java lambda for a Closure
> but the Java type system does not really allow a nice solution for
> that, which means Closure would become:
>
> interface Closure {
>   Object call(Object[] args);
>   static Closure buildClosure(MethodHandle... h) {...}
>   static Closure buildClosure(Lookup lookup, Class<?> baseClass,
> String methodName) /*throws ReflectiveOeprationException */{...}
>   // plus more here
> }
>
> (4) all old code using one of the other call methods or any doCall
> would break. Java usage would have to change to either lambdas or one
> of the buildClosure methods. Groovy usage could use the MethodHandle
> based version and only the MethodHandle based version would include
> meta information like the parameter count and types. Accessing this
> information lazy could make it a thin wrapper around the handle,
> allowing transformations from Closure to SAM cases, while still
> holding some kind of reference.
>
> (5) If I think of as lightweight as possible I automatically think of
> ValueTypes... Then I wonder... would we rewrite Closure as ValueType
> of a MethodHandle at some point (post JDK 11). If yes, should we
> investigate more here and maybe go for JKD11+ instead of JDK9 with
> Groovy 3? Frankly There is no good reason for me to go with Java 9
> anymore, since it is already outdated and not even with LTS.
>
>
> What do others think about this? Or should I just go an break some
> arms and legs... ahm...Groovy code ?
>
> bye Jochen