How do I fix the IllegalArgumentException Error I'm getting?

Discussion in 'Plugin Development' started by Lynden Sylver, Jun 15, 2021.

Thread Status:
Not open for further replies.
  1. Offline

    Lynden Sylver

    Hi, I'm newer to coding Spigot plugins and I've run into this error:

    Code:
    java.lang.IllegalArgumentException: Path cannot be null
        at org.apache.commons.lang.Validate.notNull(Validate.java:192) ~[patched_1.16.5.jar:git-Paper-735]
        at org.bukkit.configuration.MemorySection.get(MemorySection.java:237) ~[patched_1.16.5.jar:git-Paper-735]
        at org.bukkit.configuration.MemorySection.getBoolean(MemorySection.java:365) ~[patched_1.16.5.jar:git-Paper-735]
        at me.lyndensylvester.halloween.listener.EventListener.spawn(EventListener.java:121) ~[?:?]
        at com.destroystokyo.paper.event.executor.asm.generated.GeneratedEventExecutor1.execute(Unknown Source) ~[?:?]
        at org.bukkit.plugin.EventExecutor.lambda$create$1(EventExecutor.java:69) ~[patched_1.16.5.jar:git-Paper-735]
        at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:80) ~[patched_1.16.5.jar:git-Paper-735]
        at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70) ~[patched_1.16.5.jar:git-Paper-735]
        at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:624) ~[patched_1.16.5.jar:git-Paper-735]
        at org.bukkit.craftbukkit.v1_16_R3.event.CraftEventFactory.callCreatureSpawnEvent(CraftEventFactory.java:719) ~[patched_1.16.5.jar:git-Paper-735]
        at org.bukkit.craftbukkit.v1_16_R3.event.CraftEventFactory.doEntityAddEventCalling(CraftEventFactory.java:637) ~[patched_1.16.5.jar:git-Paper-735]
        at net.minecraft.server.v1_16_R3.WorldServer.addEntity0(WorldServer.java:1302) ~[patched_1.16.5.jar:git-Paper-735]
        at net.minecraft.server.v1_16_R3.WorldServer.addEntity(WorldServer.java:1203) ~[patched_1.16.5.jar:git-Paper-735]
        at net.minecraft.server.v1_16_R3.WorldAccess.lambda$addAllEntities$0(WorldAccess.java:16) ~[patched_1.16.5.jar:git-Paper-735]
        at java.util.stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:411) ~[?:?]
        at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734) ~[?:?]
        at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658) ~[?:?]
        at net.minecraft.server.v1_16_R3.WorldAccess.addAllEntities(WorldAccess.java:16) ~[patched_1.16.5.jar:git-Paper-735]
        at net.minecraft.server.v1_16_R3.SpawnerCreature.spawnMobsInternal(SpawnerCreature.java:286) ~[patched_1.16.5.jar:git-Paper-735]
        at net.minecraft.server.v1_16_R3.SpawnerCreature.spawnMobs(SpawnerCreature.java:212) ~[patched_1.16.5.jar:git-Paper-735]
        at net.minecraft.server.v1_16_R3.SpawnerCreature.a(SpawnerCreature.java:188) ~[patched_1.16.5.jar:git-Paper-735]
        at net.minecraft.server.v1_16_R3.ChunkProviderServer.lambda$tickChunks$14(ChunkProviderServer.java:867) ~[patched_1.16.5.jar:git-Paper-735]
        at net.minecraft.server.v1_16_R3.PlayerChunkMap.forEachVisibleChunk(PlayerChunkMap.java:683) ~[patched_1.16.5.jar:git-Paper-735]
        at net.minecraft.server.v1_16_R3.ChunkProviderServer.tickChunks(ChunkProviderServer.java:849) ~[patched_1.16.5.jar:git-Paper-735]
        at net.minecraft.server.v1_16_R3.ChunkProviderServer.tick(ChunkProviderServer.java:767) ~[patched_1.16.5.jar:git-Paper-735]
        at net.minecraft.server.v1_16_R3.WorldServer.doTick(WorldServer.java:576) ~[patched_1.16.5.jar:git-Paper-735]
        at net.minecraft.server.v1_16_R3.MinecraftServer.b(MinecraftServer.java:1489) ~[patched_1.16.5.jar:git-Paper-735]
        at net.minecraft.server.v1_16_R3.DedicatedServer.b(DedicatedServer.java:436) ~[patched_1.16.5.jar:git-Paper-735]
        at net.minecraft.server.v1_16_R3.MinecraftServer.a(MinecraftServer.java:1341) ~[patched_1.16.5.jar:git-Paper-735]
        at net.minecraft.server.v1_16_R3.MinecraftServer.w(MinecraftServer.java:1129) ~[patched_1.16.5.jar:git-Paper-735]
        at net.minecraft.server.v1_16_R3.MinecraftServer.lambda$a$0(MinecraftServer.java:290) ~[patched_1.16.5.jar:git-Paper-735]
        at java.lang.Thread.run(Thread.java:832) [?:?]
    Here's the code I'm trying to run in my EventListener:
    Code:
    package me.lyndensylvester.halloween.listener;
    
    import java.util.Random;
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.World;
    import org.bukkit.block.Block;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.EntityType;
    import org.bukkit.entity.LivingEntity;
    import org.bukkit.entity.Player;
    import org.bukkit.entity.Skeleton;
    import org.bukkit.entity.Zombie;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.block.BlockBreakEvent;
    import org.bukkit.event.entity.EntityDeathEvent;
    import org.bukkit.event.entity.EntitySpawnEvent;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.inventory.EntityEquipment;
    import org.bukkit.inventory.ItemStack;
    import me.lyndensylvester.halloween.utils.Utils;
    import me.lyndensylvester.halloween.Main;
    import me.lyndensylvester.halloween.items.ItemManager;
    
    public class EventListener implements Listener {
    
        private static Main plugin;
       
        @SuppressWarnings("static-access")
        public EventListener(Main plugin) {
            this.plugin = plugin;
           
            Bukkit.getPluginManager().registerEvents(this, plugin);
        }
       
        Player p;
        Block b;
        EntityType t;
       
        /**
        * BlockBreak event
        * 
        * Detect if the player broke a melon block
        * and send a success or failure spawn message
        * 
        * @param event
        */
        @EventHandler
        public void onBlockBreak(BlockBreakEvent event) {
            p = (Player) event.getPlayer();
            b = (Block) event.getBlock();
    
            if (b.getType() == Material.MELON) {
                Random rand = new Random();
                var max = 100;
                var min = 0;
                int chance = rand.nextInt(max - min + 1)  + min;
    
                if (chance > 33) {
                    Location spawnLoc = p.getLocation().add(2,0,0);
                    World world = p.getWorld();
    
                    @SuppressWarnings("unused")
                    Skeleton skeleton = (Skeleton) world.spawnEntity(spawnLoc, EntityType.SKELETON);
                    Bukkit.broadcastMessage(Utils.chat(plugin.getConfig().getString("melon_succes").replace("<player>", p.getName())));
                }
               
                else {
                    Bukkit.broadcastMessage(Utils.chat(plugin.getConfig().getString("melon_fail").replace("<player>", p.getName())));
                }
            }
           
            if (b.getType() == Material.PUMPKIN) {
                Random rand = new Random();
                var max = 100;
                var min = 0;
                int chance = rand.nextInt(max - min + 1) + min;
               
                if (chance > 50) {
                    Location spawnLoc = p.getLocation().add(2,0,0);
                    World world = p.getWorld();
                   
                    @SuppressWarnings("unused")
                    Zombie zombie =(Zombie) world.spawnEntity(spawnLoc, EntityType.ZOMBIE);
                    Bukkit.broadcastMessage(Utils.chat(plugin.getConfig().getString("pumpkin_succes").replace("<player>", p.getName())));
                }
               
                else {
                    Bukkit.broadcastMessage(Utils.chat(plugin.getConfig().getString("pumpkin_fail").replace("<player>", p.getName())));
                }
            }
           
        }
       
        /**
        * EntitySpawn event
        * 
        * Spawn a skeleton 2 blocks to the right of the player
        * 
        * @param event
        */
        @SuppressWarnings({ })
        @EventHandler
        public void spawn(EntitySpawnEvent event) {
    
                Entity entity = event.getEntity();
               
            if (plugin.getConfig().getBoolean(null, true) && (entity instanceof Skeleton)) {
                EntityEquipment  ee = ((Skeleton)entity).getEquipment();
                ee.setHelmet(new ItemStack(Material.MELON));
                ee.setHelmetDropChance(100);
            }
            if (plugin.getConfig().getBoolean(null, true) && (entity instanceof Zombie)) {
                EntityEquipment  ee = ((Zombie)entity).getEquipment();
                ee.setHelmet(new ItemStack(Material.PUMPKIN));
                ee.setHelmetDropChance(100);
            }
            if (plugin.getConfig().getBoolean(null, false)) {
                p.sendMessage("This feature has been disabled! Go to the config to re-enable it!");
            }
        }
       
        /**
        * EntityDeath event
        * 
        * Add custom Drops to the mob
        * 
        * @param event
        */
        @EventHandler
        public void onDeath(EntityDeathEvent event) {
            LivingEntity e = event.getEntity();
            Random rand = new Random();
            var max = 100;
            var min = 0;
            int chance = rand.nextInt(max - min + 1)  + min;
           
            if (e instanceof Skeleton) {
                // 50%
                if (chance < 50) {
                    e.getLocation().getWorld().dropItem(e.getLocation(), new ItemStack(Material.COAL));
                }
                // 25%
                else if ((49 < chance) && (chance < 75)) {
                    e.getLocation().getWorld().dropItem(e.getLocation(), new ItemStack(Material.IRON_INGOT));
                }
                // 13%
                else if ((74 < chance) && (chance < 88)) {
                    e.getLocation().getWorld().dropItem(e.getLocation(), new ItemStack(Material.GOLD_INGOT));
                }
                // 7%
                else if ((87 < chance) && (chance < 95))
                    e.getLocation().getWorld().dropItem(e.getLocation(), new ItemStack(Material.REDSTONE_WIRE));
                }
                // 4%
                else if ((94 < chance) && (chance < 99)) {
                    e.getLocation().getWorld().dropItem(e.getLocation(), new ItemStack(Material.DIAMOND));
                }
                // 2%
                else {
                    e.getLocation().getWorld().dropItem(e.getLocation(), new ItemStack(Material.EMERALD));
                }
        }
       
        @EventHandler
        public static void onRightClick(PlayerInteractEvent event) {
            if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
                if (event.getItem() != null) {
                    if (event.getItem().getItemMeta().equals(ItemManager.superSword.getItemMeta()))  {
                        Player p = event.getPlayer();
                        p.getWorld().createExplosion(p.getLocation(), 2.0f);
                        p.sendMessage("&7 You Dare use the Super Sword!");
                    }
                }
            }
           
        }
    }
    
    

    This is what ItemManager does:
    Code:
    package me.lyndensylvester.halloween.items;
    
    import java.util.ArrayList;
    import java.util.List;
    import org.bukkit.Material;
    import org.bukkit.enchantments.Enchantment;
    import org.bukkit.inventory.ItemFlag;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    
    publicclassItemManager {
    
        publicstaticItemStacksuperSword;
    
        publicstaticvoidinit() {
            createSuperSword();
        }
    
        privatestaticvoidcreateSuperSword() {
    
            ItemStack item = new ItemStack(Material.IRON_SWORD, 1);
            ItemMetameta = item.getItemMeta();
            meta.setDisplayName("Super Sword");
            List<String> lore = new ArrayList<>();
            lore.add("&7This is the most powerful sword");
            lore.add("&7in all of Minecradt's history");
            meta.setLore(lore);
            meta.addEnchant(Enchantment.SWEEPING_EDGE, 3, false);
            meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
            item.setItemMeta(meta);
            superSword = item;  
        }
    }
    

    This is how I have my Main file setup:
    Code:
    package me.lyndensylvester.halloween;
    
    import org.bukkit.plugin.java.JavaPlugin;
    import me.lyndensylvester.halloween.commands.HalloweenCommand;
    import me.lyndensylvester.halloween.items.ItemManager;
    import me.lyndensylvester.halloween.listener.EventListener;
    
    public class Main extends JavaPlugin {
    
        @Override
        public void onEnable() {
            new EventListener(this);
            ItemManager.init();
            getServer().getPluginManager().registerEvents(new EventListener(this), this);
            getCommand("superSword").setExecutor(new HalloweenCommand());
        }
    }
    And this is how I have HalloweenCommand setup:
    Code:
    package me.lyndensylvester.halloween.commands;
    
    import org.bukkit.Location;
    import org.bukkit.World;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.EntityType;
    import org.bukkit.entity.Player;
    import org.bukkit.entity.Skeleton;
    import me.lyndensylvester.halloween.items.ItemManager;
    
    public class HalloweenCommand implements CommandExecutor {
       
        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
            if(!(sender instanceof Player)) {
                sender.sendMessage("Only players may execute this command");
                return true;
            }
           
            Player p = (Player) sender;
           
            if (cmd.getName().equalsIgnoreCase("Halloween")) {
                p.sendMessage("Happy Halloween >:)");
                Location spawnLoc = p.getLocation().add(2,0,0);
                World world = p.getWorld();
               
                @SuppressWarnings("unused")
                Skeleton skeleton = (Skeleton) world.spawnEntity(spawnLoc, EntityType.SKELETON);
                return true;
            }
           
            if (cmd.getName().equalsIgnoreCase("superSword")) {
                p.getInventory().addItem(ItemManager.superSword);
            }
           
            else {
                p.sendMessage("You do not have the permission to execute this command");
            }
            return true;   
        }   
    }
    
    What's causing the error and how do I fix it? everything in the code is logically sound, but only the superSword works and not the EntitySpawning. Help would be greatly appreciated!
     
  2. Offline

    Shqep

    @Lynden Sylver
    Your error says it's a IllegalArgumentException and path cannot be null.
    Then you can look at your stacktrace and it's saying:
    at me.lyndensylvester.halloween.listener.EventListener.spawn(EventListener.java:121) ~[?:?]

    You can then deduce that there's a problem in the EventListener.java file, at line 121, in the method spawn().
    PHP:
    if (plugin.getConfig().getBoolean(nullfalse)) { // This line!
        
    p.sendMessage("This feature has been disabled! Go to the config to re-enable it!");
    }
    The signature of the getBoolean() method is getBoolean(path, defaultValue)
    "path cannot be null" is the error message. You get the point.

    psst @timtower wrong section no?
     
    KarimAKL likes this.
  3. Offline

    timtower Administrator Administrator Moderator

    Psst, report button no? :p

    Moved to plugin development.
     
    KarimAKL likes this.
  4. Offline

    Shqep

    Forgot the existence of that button shh tim dont make it obvious
     
    KarimAKL and timtower like this.
  5. Offline

    Lynden Sylver

    @Shqep

    I know Java, but I haven't worked with paths before.

    Are there any resources available explaining how I can identify the path I need?

    That error has been driving crazy the last couple of days.

    Also, thanks for pinpointing the source of my error, being newer to the API, I'm still learning about all the nuances of the methods I'm using.
     
    Last edited: Jun 16, 2021
  6. Offline

    Shqep

    @Lynden Sylver
    Assuming this is a yaml file:
    Code:
    testString:
      key1: true
      key2: "Hello"
    testString2:
      key3: 1.0
      key4:
      - "List"
      - "of"
      - "String"
    Consider the yaml file as a very big HashMap, and the path is just the key to point to the value. So if you want to get the list of string above, you need to specify the path as "testString2.key4". Likewise:
    Code:Java
    1. config.getBoolean("testString.key1"); // returns true
    2. config.getString("testString.key2"); // returns "Hello"
    3. config.getDouble("testString2.key3"); // returns 1.0
    4. config.getStringList("testString2.key4"); // returns a list containing "List", "of", and "String"
    5. config.getKeys(false); // returns a list of the main keys "testString" and "testString2"


    You can specify the second argument as the "default value":
    Code:Java
    1. config.getBoolean("testString.key4", true); // "testString.key4" path returns null, so true is returned instead
     
  7. Offline

    Lynden Sylver

    @Shqep

    Just a quick follow-up,

    How would I pass a casted Player into my EntitySpawnEvent so that I can use p.sendMessage?

    I understand Player is not a child of the EntitySpawnEvent, so what's a workaround that would let me pass a casted Player so I can send the player a message?

    I already have Player p declared in global scope, but how can I instantiate it for use in EntitySpawnEvent? (Refer back to my original post for the EventListener Class where I declare Player as p)
     
  8. Offline

    Shqep

    @Lynden Sylver
    That really didn't make a lot of sense. EntitySpawnEvents are only called only when an entity is created/spawned. They have absolutely nothing to do with a player.
    If you want to detect who used the spawn egg, you might want to refer to the event PlayerInteractEvent or some similar ones.

    If you want to send a player a message (why?), use the Bukkit.getPlayer(name) or Bukkit.getPlayer(uuid). You don't create a new instance of Player because the new thing won't be bound to any actual players. Unless you know exactly what you are doing and how to bind that new instance to an existing player for Bukkit to recognize, it's better to just stay away.

    Defining a Player property for the class is a very bad idea. Just imagine, what if there are many players being assigned to that variable, they keep overriding each other and from your standpoint, you do not know who you are sending the message to.

    Show Spoiler
    Some more advice since you are new to the api:
    1. You have a class named HalloweenCommand, why not make another small class for the supersword command? Cleans up a bit and you don't have to call checks for cmd.getName().
    Code:Java
    1. // MainClass
    2. public void onEnable() {
    3. getCommand("halloween").setExecutor(new HalloweenCommand());
    4. getCommand("supersword").setExecutor(new SuperswordCommand());
    5. }
    6.  
    7. // HalloweenCommand's
    8. public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
    9. // No need to check cmd.getName() anymore since it's always "halloween"
    10. assert cmd.getName().equalsIgnoreCase("halloween");
    11. }
    12.  
    13. // SuperswordCommand's
    14. public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
    15. // No need to check cmd.getName() anymore since it's always "supersword"
    16. assert cmd.getName().equalsIgnoreCase("supersword");
    17. }


    2. Currently from your codes, the cmd.getName() will never be "halloween" since you never specified its executor.
    Code:Java
    1. getCommand("halloween").setExecutor(...);


    3. You're not checking for permissions in your command class:
    Code:Java
    1. // Reread it and you should see it's pretty weird.
    2. if (cmd.getName().equalsIgnoreCase("superSword")) {
    3. p.getInventory().addItem(ItemManager.superSword);
    4. } else {
    5. p.sendMessage("You do not have the permission to execute this command");
    6. }
    7.  
    8. // Proper way 1
    9. if(p.hasPermission("permission.node")) {
    10. // Do your stuff.
    11. } else p.sendMessage("no perms L");
    12.  
    13. // Proper way 2 "negative checks"
    14. if(!p.hasPermission("permission.node")) {
    15. p.sendMessage("no perms lol");
    16. return true;
    17. }
    18. // Stuff down here to avoid too much indentation.


    4. You keep trying to get a key from path null in config in the spawn event. But I assume you already got this fixed by now.

    Other random stuff such as instantiating a Random instance every time the event is called, kind of inefficient, you can probably define a global scope variable for this class.
    Also why static on an event handler method?
     
Thread Status:
Not open for further replies.

Share This Page