On 11.03.2018 20:22, Rony G. Flatscher wrote: > Well, still trying to find out what the reason is, that core reflection's > invoke behaves > differently to MethodHandle's invokeWithArguments in one single case so far > (using the method > java.utli.Arrays.asList(...)). > > Here is a little Java program that excercises reflective access to > "java.util.Arrays.asList(T... a)" using core reflection, i.e. > "Method.invoke(Object obj, > Object... args)" and "MethodHandle.invokeWithArguments(Object... arguments)": > > import java.util.*; > > import java.lang.reflect.*; > import java.lang.invoke.*; > > class DemoAsListProblem > { > public static void main (String args[]) > { > String arrNames[]=new String[] { "anne", "bert", "celine"}; > System.out.println("[1] (main) arrNames=\""+arrNames+"\", > .toString()=\""+arrNames.toString()+"\""); > List listNames=Arrays.asList(arrNames); > System.out.println("[2] (main) after invoking > Arrays.asList(arrNames), listNames=\""+listNames+"\""); > System.out.println("\ninvoking testReflective() ...\n"); > > testReflective(); > } > > public static void testReflective() > { > String arrNames[]=new String[] { "anne", "bert", "celine"}; > System.out.println("[3] (testReflective) > arrNames=\""+arrNames+"\", .toString()=\""+arrNames.toString()+"\""); > > Method methAsList=null; > List listNames=null; > try { > Class paramTypes[]=new Class[] { (new Object[0]).getClass() }; > methAsList=Arrays.class.getDeclaredMethod("asList", > paramTypes); > System.out.println("--- (core reflection) Method object > asList: "+methAsList); > System.out.println("\n--- (core reflection) now invoking > Arrays.asList() via Method.invoke(...):"); > > listNames=(List) methAsList.invoke( null, (Object[]) new > Object[]{arrNames} ); // static method > System.out.println("[4a] --- (CR) methAsList.invoke( null, > (Object[]) new Object[]{arrNames} ) -> listNames=\""+listNames+"\""); > > listNames=(List) methAsList.invoke( null, (Object) new > Object[]{arrNames} ); // static method > System.out.println("[4b] --- (CR) methAsList.invoke( null, > (Object) new Object[]{arrNames} ) -> listNames=\""+listNames+"\""); > > // "java.lang.IllegalArgumentException: wrong number of arguments": > // listNames=(List) methAsList.invoke( null, (Object[]) > arrNames ); // static method > // System.out.println("[5a] --- (CR) methAsList.invoke( null, > (Object[]) arrNames ) -> listNames=\""+listNames+"\""); > > listNames=(List) methAsList.invoke( null, (Object) arrNames > ); // static method > System.out.println("[5b] --- (CR) methAsList.invoke( null, > (Object) arrNames ) -> listNames=\""+listNames+"\""); > } > catch (Throwable t) > { > System.err.println("oops #1: "+t); > t.printStackTrace(); > System.exit(-1); > } > > System.out.println("\n--- (MH) now invoking Arrays.asList() via > MethodHandle.invokeWithArguments(...):"); > MethodHandles.Lookup lookup=MethodHandles.lookup(); > MethodHandle mh=null; > try { > mh=lookup.unreflect(methAsList); > System.out.println("--- (MH) unreflected MethodHandle mh: > "+mh); > > listNames=(List) mh.invokeWithArguments( (Object[]) new > Object[]{arrNames} ); > System.out.println("[6a] --- (MH) mh.invokeWithArguments( > (Object[]) new Object[]{arrNames} ) -> listNames=\""+listNames+"\""); > > listNames=(List) mh.invokeWithArguments( (Object) new > Object[]{arrNames} ); > System.out.println("[6b] --- (MH) mh.invokeWithArguments( > (Object) new Object[]{arrNames} ) -> listNames=\""+listNames+"\""); > > listNames=(List) mh.invokeWithArguments( (Object[]) arrNames > ); > System.out.println("[7a] --- (MH) mh.invokeWithArguments( > (Object[]) arrNames ) -> listNames=\""+listNames+"\""); > > listNames=(List) mh.invokeWithArguments( (Object) arrNames ); > System.out.println("[7b] --- (MH) mh.invokeWithArguments( > (Object) arrNames ) -> listNames=\""+listNames+"\""); > > } > catch (Throwable t) > { > System.err.println("oops #2: "+t); > t.printStackTrace(); > System.exit(-2); > } > } > } > > Compiling and running it under 9.0.4 yields the following output: > > [1] (main) arrNames="[Ljava.lang.String;@27ddd392", > .toString()="[Ljava.lang.String;@27ddd392" > [2] (main) after invoking Arrays.asList(arrNames), listNames="[anne, > bert, celine]" > > invoking testReflective() ... > > [3] (testReflective) arrNames="[Ljava.lang.String;@2a18f23c", > .toString()="[Ljava.lang.String;@2a18f23c" > --- (core reflection) Method object asList: public static java.util.List > java.util.Arrays.asList(java.lang.Object[]) > > --- (core reflection) now invoking Arrays.asList() via Method.invoke(...): > [4a] --- (CR) methAsList.invoke( null, (Object[]) new Object[]{arrNames} > ) -> listNames="[anne, bert, celine]" > [4b] --- (CR) methAsList.invoke( null, (Object) new Object[]{arrNames} > ) -> listNames="[[Ljava.lang.String;@2a18f23c]" > [5b] --- (CR) methAsList.invoke( null, (Object) arrNames ) > -> listNames="[anne, bert, celine]" > > --- (MH) now invoking Arrays.asList() via > MethodHandle.invokeWithArguments(...): > --- (MH) unreflected MethodHandle mh: MethodHandle(Object[])List > [6a] --- (MH) mh.invokeWithArguments( (Object[]) new Object[]{arrNames} > ) -> listNames="[[Ljava.lang.String;@2a18f23c]" > [6b] --- (MH) mh.invokeWithArguments( (Object) new Object[]{arrNames} > ) -> listNames="[[Ljava.lang.Object;@13a57a3b]" > [7a] --- (MH) mh.invokeWithArguments( (Object[]) arrNames ) > -> listNames="[anne, bert, celine]" > [7b] --- (MH) mh.invokeWithArguments( (Object) arrNames ) > -> listNames="[[Ljava.lang.String;@2a18f23c]" > > So a String array is turned into a List using Arrays.asList(strArray). Doing > it with core > reflection yields different results to doing it with invokeWithArguments(). > > I would have expected that [4a] and [6a] would behave the same. > > Using reflective invoke() and invokeWithArguments() has been working for my > bridge for all the > test units (using literally the same arguments in both cases) > interchangeably, the one exception > is Arrays.asList(). > > Maybe I am not seeing the obvious (having done too much "close-up tests" for > quite some time now). > So any hint, insight, help would be really appreciated! > > ---rony As a few months have gone by without any follow-ups, I have been wondering whether there is a solution at all, if this is a problem rooted in the current implementation of MethodHandle methods not being 100% compatible with reflective invoke (which may imply that one needs to stick to use reflective invoke and forgo MethodHandle invokes for good).
---rony
_______________________________________________ mlvm-dev mailing list mlvm-dev@openjdk.java.net http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev