Wie soll ich LambdaMetaFactory in meinem Anwendungsfall verwenden?

Obwohl ich die gesamte mir bekannte Dokumentation gelesen habe, kann ich ein Problem mit der Verwendung von Lambdas zur Ausführung einer Methode nicht lösen. Um ein bisschen Hintergrundwissen zu vermitteln, ist mein Anwendungsfall ein Pluginsystem. Ich verwende eine Annotation (@EventHandle), die jeder Methode zugewiesen werden kann. Ich benutze Reflektion und durchlaufe jede Methode in der Klasse und überprüfe, ob die Annotation vorhanden ist. Wenn dies der Fall ist, wird die Methode zu einem Handler-Objekt hinzugefügt (das zu einer Liste hinzugefügt wird, um jeden "Tick" zu verarbeiten). Hier ist meine Handler-Klasse:

package me.b3nw.dev.Events;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.lang.invoke.*;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

@Slf4j
public class Handler {

    @Getter
    private final Method method;
    @Getter
    private final EventHandle handle;
    private final MethodHandles.Lookup lookup;
    private final MethodHandle methodHandle;
    private final EventHandler invoker;

    public Handler(Method method, EventHandle handle) throws Throwable {
        this.method = method;

        log.info(method.getGenericReturnType() + "");

        for(Type type : method.getParameterTypes()) {
            log.info(type.getTypeName());
        }

        this.handle = handle;
        this.lookup = MethodHandles.lookup();
        this.methodHandle = lookup.unreflect(method);

        log.info("" + methodHandle.type().toMethodDescriptorString());

        this.invoker = (EventHandler) LambdaMetafactory.metafactory(lookup, "handle", MethodType.methodType(EventHandler.class), methodHandle.type(), methodHandle, methodHandle.type()).getTarget().invokeExact();
    }

    public void invoke(GameEvent evt) throws Throwable {
        invoker.handle(evt);
    }

}

n der aktuellen Iteration dieser Klasse wirke ich direkt auf die Funktionsschnittstelle EventHandler, Quelle:

package me.b3nw.dev.Events;

@FunctionalInterface
public interface EventHandler {

    boolean handle(GameEvent evt);

}

Zurzeit erhalte ich folgende Fehlermeldung:

ERROR   m.b.d.H.GamemodeHandler - 
java.lang.AbstractMethodError: me.b3nw.dev.Events.Handler$Lambda$3/1704984363.handle(Lme/b3nw/dev/Events/GameEvent;)Z
    at me.b3nw.dev.Events.Handler.invoke(Handler.java:40) ~[classes/:na]
    at me.b3nw.dev.Handlers.GamemodeHandler.userEventTriggered(GamemodeHandler.java:34) ~[classes/:na]

GamemodeHandler ruft nur die aufrufende Methode in der Handler-Klasse auf.

So gibt es einen AbstractMethodError aus, wenn ich direkt in EventHandler umsetze und ausführe. Wenn ich ihn nicht umsetze, erhalte ich einen anderen Fehler:

java.lang.invoke.WrongMethodTypeException: expected ()EventHandler but found ()void
    at java.lang.invoke.Invokers.newWrongMethodTypeException(Invokers.java:294) ~[na:1.8.0_45]
    at java.lang.invoke.Invokers.checkExactType(Invokers.java:305) ~[na:1.8.0_45]
    at me.b3nw.dev.Events.Handler.invoke(Handler.java:40) ~[classes/:na]
    at me.b3nw.dev.Handlers.GamemodeHandler.userEventTriggered(GamemodeHandler.java:34) ~[classes/:na]

Der geänderte Handler, um Änderungen widerzuspiegeln:

package me.b3nw.dev.Events;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.lang.invoke.*;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

@Slf4j
public class Handler {

    @Getter
    private final Method method;
    @Getter
    private final EventHandle handle;
    private final MethodHandles.Lookup lookup;
    private final MethodHandle methodHandle;
    private final MethodHandle invoker;

    public Handler(Method method, EventHandle handle) throws Throwable {
        this.method = method;

        log.info(method.getGenericReturnType() + "");

        for(Type type : method.getParameterTypes()) {
            log.info(type.getTypeName());
        }

        this.handle = handle;
        this.lookup = MethodHandles.lookup();
        this.methodHandle = lookup.unreflect(method);

        log.info("" + methodHandle.type().toMethodDescriptorString());

        this.invoker = LambdaMetafactory.metafactory(lookup, "handle", MethodType.methodType(EventHandler.class), methodHandle.type(), methodHandle, methodHandle.type()).getTarget();
    }

    public void invoke(GameEvent evt) throws Throwable {
        invoker.invokeExact();
    }

}

Diese Klasse hat eine Methode, die mit Annotationen versehen ist und die Signatur der Funktionsschnittstelle implementieren soll, aber .. eindeutig nicht :( Hier ist die Klasse:

package me.b3nw.dev.Gamemode;

import lombok.extern.slf4j.Slf4j;
import me.b3nw.dev.Events.EventHandle;
import me.b3nw.dev.Events.GameEvent;

@Slf4j
public class Vanilla extends Gamemode {

    public void testMethod() {

    }

    @EventHandle(type = EventHandle.Type.NICKANNOUNCE)
    public boolean testMethod2(GameEvent evt) {
        log.info("Fuck yeah!"/* + evt*/);
        return true;
    }

}

Wie behebe ich das, verwende ich Lambdas hier völlig falsch?

Vielen Dank

Antworten auf die Frage(2)

Ihre Antwort auf die Frage