1

My problem is the following: I'm trying to use invoke dynamic but I'm having problems with findVirtual and invoke.

Class<?> returnTypeClass = Class.forName("com.etc1.foo.FIXML"); 
MethodHandles.Lookup lookup = MethodHandles.lookup();




MethodType methodType = MethodType.methodType(returnTypeClass ,returnTypeClass); //The method which will be invoked has as a param FIXML object and return a FIXML object

MethodHandle methodHandle = lookup.findVirtual(
                        com.etc2.foo.GMD, 
                        "name_method", 
                        methodType);

I have the first problem in findVirtual, I'm getting a methodHandle with the next MethodType (GMD,FIXML)FIXML --> this is not correct because my method is "public FIXML name_method(FIXML)" and findVirtual is creating a methodHandle "public FIXML name_method(GMD,FIXML)", I understand findVirtual is using "com.etc2.foo.GMD" as a param. First question from here: How can I get findVirtual to return a methodHandle FIXML name_method(FIXML)??

The second problem comes from the first one, I think... When I invoke the method by methodHandle

com.etc1.foo.FIXML fixml;
com.etc1.foo.FIXML fixml2;
fixml2 = (FIXML) methodHandle.invoke(fixml);

I get the following error "java.lang.invoke.WrongMethodTypeException: cannot convert MethodHandle(GMD,FIXML)FIXML to (Object)Object"

Actually... I have been looking into other questions and I tried different solutions and nothing worked.

Holger
  • 285,553
  • 42
  • 434
  • 765
dbenor
  • 55
  • 1
  • 8

2 Answers2

0

After breaking my brain for hours I got the answer. The method findVirtual is returning the correct MethodHandle because the parameter added (GMD,FIXML) is, actually, the object which will call the method, therefore I have to invoke the method by:

fixml2Obj = (FIXML) methodHandle.invokeWithArguments((Object) Class.forName("com.etc2.foo.GMD").newInstance(), fixmlObj);

I share couple links which gave me information about this:

Read "Method handle creation": http://docs.oracle.com/javase/7/docs/api/java/lang/invoke/MethodHandle.html

http://octodecillion.com/blog/java-reflection-on-a-message-using-methodhandle/

dbenor
  • 55
  • 1
  • 8
0

You could also stumble across the same thing when using invokedynamic, because the JVM creates parameters that are handed over to the bootrstrap method, where method resolution will take place. To circumvent the error you found you will have to remove the class on which the method should be called from the MethodType argument.

public static CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType type) {
    final MethodHandle mh = caller.findVirtual(type.parameterType(0), name, type.dropParameterTypes(0, 1));
    final MutableCallSite callSite = new MutableCallSite(mh);
    return callSite;
}
lschuetze
  • 1,218
  • 10
  • 25