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