Uploaded image for project: 'Spigot'
  1. Spigot
  2. SPIGOT-893

JDK behavior change breaks Listeners that override a generic method

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Major Major
    • None
    • None
    • Java 7u80 (or above)
      Java 8 (any version)

      Consider the following example:

      Base.java
      public abstract class Base<T extends Event> implements Listener {
          abstract void method(T event);
      }
      
      Derived.java
      public class Derived extends Base<BlockPlaceEvent> {
          @EventHandler
          void onEvent(BlockPlaceEvent event) {}
      }
      

      If you examine Derived with javap, you discover that it actually has two methods.

      Compiled from "Derived.java"
      public class Derived extends Base<org.bukkit.event.block.BlockPlaceEvent> {
        public Derived();
        void onEvent(org.bukkit.event.block.BlockPlaceEvent);
        void onEvent(org.bukkit.event.Event);
      }
      

      In Java 7u79 and earlier, the @EventHandler annotation only exists on the void onEvent(org.bukkit.event.block.BlockPlaceEvent) method. However, a change was made to the JDK (see https://bugs.openjdk.java.net/browse/JDK-6695379) to copy the annotation to the overridden method, that being void onEvent(org.bukkit.event.Event).

      Bukkit reflectively looks for the getHandlerList method for any class in the parameter list of a function annotated with @EventHandler. In earlier versions of Java 7, it would only notice the void onEvent(BlockPlaceEvent) version and successfully register the class. In code compiled with the above mentioned versions, @EventHandler is copied to the void onEvent(Event) method, and then an exception is thrown when Bukkit can't find the getHandlerList method.

            Unassigned Unassigned
            ams2990 Andrew Shulman
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: