Solved What does "Static getHandlerList method required!" mean?

Discussion in 'Spigot Plugin Development' started by Fredashay, Oct 10, 2017.

  1. What does "Static getHandlerList method required!" mean?

    Does it want me to create an event handler method named getHandlerList() in my class source file?

    I'm looking here in the Javadocs: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/HandlerList.html but I still don't understand what the problem is or what I need to code in my class source to fix it.

    Despite the exception, my plugin and all its event handlers seem to be working fine, so is there a way to just create an empty method named getHandlerList() so this exception doesn't get thrown?

    Or am I being a clueless noob about something? :-/

    upload_2017-10-10_17-50-43.png
     
  2. Hi, can you show us the code where the error is happening?
     
    • Like Like x 1
  3. Take a look at https://bukkit.gamepedia.com/Event_API_Reference, and scroll down to "Custom Event Example".
     
    • Like Like x 1
    • Useful Useful x 1
  4. I feel like you're trying to create listeners but you're extending Event.
     
    • Like Like x 1
  5. The stack trace says it's happening on line 177:

    Code (Text):

    @Override
        public void onEnable() {
           pdfFile = getDescription();
           getServer().getPluginManager().registerEvents(this,this);    //  <-- This is line 177 in Eclipse
           logger = Logger.getLogger("Minecraft");      
           if (getServer().getWorld("world") == null) {
                 boolean searching = true;
                 List<World> worlds = (List<World>) getServer().getWorlds();                  
                 if (worlds.size() <= 0) {
                     logger.info("[" + pdfFile.getName() + "] Could not find any worlds!  How is this possible? ");
                     }
                 else {
                     int worldIx = 0;
                     while (worldIx < worlds.size()) {
                         globalWorld = worlds.get(worldIx);
                         logger.info("[" + pdfFile.getName() + "] Found world '" + globalWorld.getName() + "' (" + globalWorld.getSeed() + "). ");
                         if (globalWorld.getName().trim().equalsIgnoreCase("world")) {
                             searching = false;                    
                             }
                         worldIx = worldIx + 1;                
                         }
                     if (searching) {
                         logger.info("[" + pdfFile.getName() + "] Could not find the world!  Strange_Things(tm) may happen! ");
                         globalWorld = worlds.get(0);                    
                         }
                     }
               }
           else {
               globalWorld = getServer().getWorld("world");  
               }
           String fileName = pdfFile.getName() + ".properties";  
             getProperties(fileName);        
             if (debug) {
                 logger.info("[" + pdfFile.getName() + "] Debug is on. ");
                 }
             else {
                 logger.info("[" + pdfFile.getName() + "] Debug is off. ");
                 }        
             dbName = "Fredashay.db";
           sqlInit(dbName);
             clock(1000);
            }
     
     
  6. It's a class with a crapton of event hander methods in it...
     
  7. JustisR

    Supporter

    You're trying to use the abstract PlayerEvent class as an @EventHandler method's event argument.
    This class was not meant to be used as an event; in fact, I'm curious how you attempted utilized it and on what trigger, seeing as the only real method it provides is #getPlayer().

    Remove that useless event and you should be all good. (Unless you're using other abstract event classes as events)
     
    • Like Like x 1
  8. Okay, I found out the problem (sort'a)...

    I have a class that has nothing but event handlers in it. So I commented out half the event handlers from the middle to the end and tested it. Using a "binary search algorithm," I moved the /* halfway again up or down depending on whether or not it threw that exception.

    The result? After several "binary search" iterations, I discovered that just having either of these two event handlers existing in my code causes the exception to be thrown, and removing them no longer causes the exception:

    Code (Text):

        /*
        //   USING EITHER OF THESE TWO EVENTS CAUSE AN IllegalPluginAccessException TO BE THROWN:
       // TODO Further experiments on another day and dig deeper into the Javadocs...

        @EventHandler
        public void blockPistonEvent(BlockPistonEvent event) {      
            }

        @EventHandler
        public void playerBucketEvent(PlayerBucketEvent event) {
            }
        /* */
     
    With these two event handlers commented out, the exception doesn't get thrown when my plugin is loaded.

    I don't know if it's because these two plugins require additional setup which I'm not doing correctly...or if it's because there's a bug in the Spigot API. (It's probably because I'm doing something wrong, lol. But I can do what I need without catching either of these events.)
     
  9. But I'm not doing that. None of the event handlers in my code use PlayerEvent as its argument. This gives me more reason to think there may be a bug in the Spigot API.

    Like I said above, the exception went away when I removed the handlers for BlockPistonEvent and PlayerBucketEvent.
     
    #9 Fredashay, Oct 11, 2017
    Last edited: Oct 11, 2017
  10. JustisR

    Supporter

    That's interesting. The error you mention in your first post directly references PlayerEvent.
    Seeing as I didn't have your whole source and couldn't verify this, I tested the process I described and as expected reproduced the same results that you reported.

    Both of these events are valid, (or should be).
    What spigot version are you using to test with?
    I'd suggest creating a separate plugin with just those events and seeing if you get the same results.
    That is, if you're not entirely satisfied with simply having prevented the error from occurring.
     
  11. Yes, that's interesting, indeed, since I never specifically used PlayerEvent in my plugin (but I do have PlayerJoinEvent, PlayerMoveEvent, and a few other player-related events). That's why I'm beginning to suspect that the problem may be with the API.

    1.12.2
    In fact, I just ran BuildTools yesterday afternoon to make sure I'm on the absolutely latest server.

    I'm satisfied since I can do what I want without those two events, but I would like to know what I'm doing wrong since I've written many plugins with events without problems. Only these two specific events give me problems.

    So I'll try what you suggest and see what happens: build a bare-bones plugin that does nothing and has nothing in it except those two events...

    I'll let you know what happens...
     
    #11 Fredashay, Oct 11, 2017
    Last edited: Oct 12, 2017
  12. The world's simplest plugin...

    Code (Text):

    package FredashaySpigotDebugPlayerBucketEvent;

    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerBucketEvent;
    import org.bukkit.plugin.java.JavaPlugin;

    public class MyPlugin extends JavaPlugin implements Listener {
       
       @Override
        public void onEnable() {
           getServer().getPluginManager().registerEvents(this,this);
            }
           
       @EventHandler
       public void playerBucketEvent(PlayerBucketEvent event) { }
       
        }
     
    upload_2017-10-11_19-16-5.png
     
    • Informative Informative x 1
  13. Code (Text):

    package FredashaySpigotDebugBlockPistonEvent;

    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.BlockPistonEvent;
    import org.bukkit.plugin.java.JavaPlugin;

    public class MyPlugin extends JavaPlugin implements Listener {
       
       @Override
        public void onEnable() {
           getServer().getPluginManager().registerEvents(this,this);
            }
       
        @EventHandler
        public void blockPistonEvent(BlockPistonEvent event) {
            }
        }
     
    upload_2017-10-11_19-18-45.png
     
    • Informative Informative x 1
  14. JustisR

    Supporter

    I see.

    Both of those classes are abstract.
    I don't recall their history, but a quick look at the javadocs shows that they have been split into:
    PlayerBucketEmptyEvent, PlayerBucketFillEvent
    For the PlayerBucketEvent

    And BlockPistonExtendEvent, BlockPistonRetractEvent
    For BlockPistonEvent.

    The abstract PlayerBucketEvent class is what extends PlayerEvent and was giving that error that you encountered earlier, likely because the method that referenced it was loaded in first.

    In short, I was wrong about both of the classes being valid and should have looked at the updated javadocs better before replying.
     
    • Like Like x 1
  15. Aha! Well then, we both learned something :)

    Thanks much for your help!!! :)
     
    • Friendly Friendly x 1

Share This Page