Using the code
TransferExecutor transferExecutor= new TransferExecutorImpl();
Function<Transfer, Void> commonLambda = transferExecutor::execute;
you are binding the Function to a particular instance of TransferExecutor. Your dynamic creation code lacks an instance for the invocation of the instance method TransferExecutorImpl.execute. That’s what the exception tries to tell you.
An instance method needs a target instance to be invoked on, hence your target method has a functional signature of (TransferExecutor,Transfer)→Void.
You can either, create a BiFunction<TransferExecutor,Transfer, Void> out of this method or bind an instance to it like with your transferExecutor::execute method reference. For the latter
change the invoked type to receive an instance of TransferExecutor
MethodType invokedType = MethodType.methodType(
Function.class, TransferExecutorImpl.class);
provide the argument at the invocation:
… .getTarget().invokeExact((TransferExecutorImpl)transferExecutor);
Note that there is still a subtle difference. The statement Function<Transfer, Void> commonLambda = transferExecutor::execute; refers to the interface method while the method you have identified via your annotation is the method declared in TransferExecutorImpl.
Regarding binding captured values, see this and that answer for more explanation and examples.