I have a method that is suppose to take in the classname, argument, and method name as parameters and invoke the method depending on which class it finds it in. The method:
Method[] methods = className.getDeclaredMethods();
for (Method meth: methods) {
if (meth.getName().equalsIgnoreCase(methodName)) {
try {
MethodType mt = MethodType.methodType(boolean.class, String.class);
MethodHandles.Lookup caller = MethodHandles.lookup();
MethodHandle handle = caller.findVirtual(Utilities.class, meth.getName(), mt);
/*
* Trying to invoke using lambdaMetaFactory
*/
MethodType methodType = MethodType.methodType(boolean.class);
MethodType invokedType = MethodType.methodType(BooleanSupplier.class);
/*
* Throws java.lang.invoke.LambdaConversionException: Incorrect number of parameters for instance method
* invokeVirtual com.grainger.Automation.Utilities.navigateToUrl:(String)boolean; 0 captured parameters,
* 0 functional interface method parameters, 1 implementation parameters
*/
CallSite site = LambdaMetafactory.metafactory(caller, "getAsBoolean", invokedType, methodType, handle, methodType);
MethodHandle factory = site.getTarget();
BooleanSupplier r = (BooleanSupplier) factory.invoke();
System.out.println(r.getAsBoolean());
/*
* Trying to invoke using Method Handle
*/
/*
* Trying to invoke the method handle here, but it fails with:
* java.lang.invoke.WrongMethodTypeException: cannot convert MethodHandle(Utilities,String)boolean to (Object)Object
* methodArguments is an ArrayList<> that is initialized and populated before
*/
System.out.println(handle.invokeWithArguments(methodArguments.toArray())); //Output B
/*
* Invoking it directly with a string as an argument throws this execption:
* com.sun.jdi.InvalidTypeException: Generated value (java.lang.String) is not compatible with declared type (java.lang.Object[]). occurred invoking method.
*/
System.out.println(handle.invokeExact("www.google.com"));
// keywordResult = (Boolean) handle.invoke("www.google.com");
/*
* Using the regular Reflections API, the method invoke works but is slow
*/
// keywordResult = (Boolean) meth.invoke(classInstance, methodArguments); //Regular refection call to invoke the function
break;
} catch (Throwable e) {
System.out.println(e.getMessage());
keywordResult = false;
}
}
}
The method I'm trying to invoke is located in a separate class within the same package. This is method definition:
public boolean navigateToUrl(String strUrl) {
return true;
}
When I try to invoke the function using the lambdametafactory, I get a LambdaConversionException. When I try to invoke the method using method handle, I get the exception Java.lang.invoke.WrongMethodTypeException when invoking with arguments and sending in an ArrayList<>. I get a com.sun.jdi.InvalidTypeException when doing invokExact with a String as the argument. All this is also listed above in the comments.
I'm not able to figure out what I'm doing wrong here. Any help would be greatly appreciated! If their is anything I'm missing from the code, please let me know!