mlvm-dev Digest, Vol 117, Issue 1

Jesper Steen Møller jesper at selskabet.org
Fri Jun 8 15:21:39 UTC 2018


Hi Rony

I can't see anything wrong with the behaviour of invokeWithArguments here, but the Method.invoke is odd.
Considering that:
	Arrays.asList(arrNames); 
works as intended, it's quite reasonable that 

	mh.invokeWithArguments(arrNames);

behaves the same.

So if anything, it's Method.invoke which is surprising.

-Jesper

On 8 Jun 2018, at 14.00, mlvm-dev-request at openjdk.java.net wrote:
> 
> Send mlvm-dev mailing list submissions to
> 	mlvm-dev at openjdk.java.net
> 
> To subscribe or unsubscribe via the World Wide Web, visit
> 	http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
> or, via email, send a message with subject or body 'help' to
> 	mlvm-dev-request at openjdk.java.net
> 
> You can reach the person managing the list at
> 	mlvm-dev-owner at openjdk.java.net
> 
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of mlvm-dev digest..."
> 
> 
> Today's Topics:
> 
>   1. Re: A pure Java example with reflective access behaving
>      differently with invokeWithArguments() compared to core
>      reflection's invoke() (Re: Strange observation:
>      MethodHandle.invokeWithArguments() would not work, whereas
>      Method.invoke() would with the very same arguments (Rony G. Flatscher)
> 
> 
> ----------------------------------------------------------------------
> 
> Message: 1
> Date: Fri, 8 Jun 2018 12:07:53 +0200
> From: "Rony G. Flatscher" <Rony.Flatscher at wu.ac.at>
> To: mlvm-dev at openjdk.java.net
> Subject: Re: A pure Java example with reflective access behaving
> 	differently with invokeWithArguments() compared to core reflection's
> 	invoke() (Re: Strange observation: MethodHandle.invokeWithArguments()
> 	would not work, whereas Method.invoke() would with the very same
> 	arguments
> Message-ID: <79695c18-ca46-fd68-6dcb-024018c31e92 at wu.ac.at>
> Content-Type: text/plain; charset="utf-8"
> 
> 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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20180608/aab1fbfe/attachment-0001.html>


More information about the mlvm-dev mailing list