Question Null Exception on getCommand

  • After careful consideration and due to limited usage, we’ve made the decision to discontinue the PaperMC forums. Moving forward, we recommend using Hangar for plugin uploads, and for all other community discussions and support, please join us on Discord.

mackaroni

New member
Oct 9, 2023
2
0
1
getting this error:

Code:
java.lang.NullPointerException: Cannot invoke "org.bukkit.command.PluginCommand.setExecutor(org.bukkit.command.CommandExecutor)" because the return value of "me.mackaroni.testplugin.TestPlugin.getCommand(String)" is null

my onEnable:

Code:
public void onEnable() {
        // Plugin startup logic
        Bukkit.getConsoleSender().sendMessage("[TEST PLUGIN]This Plugin Works!");
        //Bukkit.getPluginManager().registerEvents(new JoinMessage(), this);

        this.getCommand("doctor").setExecutor(new Heal());
    }

my paper-plugin.yml:

Code:
name: TestPlugin
version: 1.0.1
main: me.mackaroni.testplugin.TestPlugin
api-version: '1.20'

commands:
  doctor:
    description: "Heals player to full"
    usage: "/heal"

my heal class:

Code:
package me.mackaroni.testplugin;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;

public class Heal implements CommandExecutor {

    @Override
    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, String[] args) {
        // checks command alias == "doctor"
        if (label.equalsIgnoreCase("doctor")) {
            // check that player is sending command
            if (!(sender instanceof Player player)) {
                sender.sendMessage(Component.text("[HEAL]Only Players Can Use This Command"));
                return true;
            }
            // check that player has perms for doctor.use
            if (!player.hasPermission("doctor.use")) {
                player.sendMessage(
                        Component.text("[HEAL]Cannot Use This Command").color(NamedTextColor.RED)
                );
                return true;
            }
            // "/doctor" input
            if (args.length == 0) {
                TextComponent message = Component.text("[HEAL]Want To Be Healed?")
                        .color(NamedTextColor.GOLD)
                        .decoration(TextDecoration.BOLD, true);
                message.clickEvent(ClickEvent.runCommand("/doctor healme"));
                message.hoverEvent(HoverEvent.showText(
                        Component.text("Click To Be Healed")
                                .color(NamedTextColor.GREEN)
                                .decoration(TextDecoration.ITALIC, true))
                );
                player.sendMessage(message);
                return true;
            }
            // "/heal" helper call
            if (args[0].equalsIgnoreCase("healme")) {
                player.setHealth(20.0);
                player.sendMessage(Component.text("[HEAL]You've Been Healed")
                        .color(NamedTextColor.GREEN)
                );
                return true;
            }
            // error pickup/redirect
            player.sendMessage(Component.text("[HEAL]Usage: /doctor?")
                    .color(NamedTextColor.RED)
            );
            return true;
        }
        return false;
    }

}
 
Last edited:

Notro

New member
Aug 23, 2023
9
0
1
YAML file is sensitive for Indentation, make sure everything is indented correctly.
More than that I would suggest a recode for this command.

Java:
package me.notro.sumowarriors.commands;

import lombok.NonNull;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;

public class HealCommand implements CommandExecutor {

    @Override
    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, String[] args) {
        if (!(sender instanceof Player player)) {
            sender.sendMessage(
                    Component.text("[HEAL] Only players can Use this command")
                            .color(NamedTextColor.RED)
            );
            return false;
        }

        if (!player.hasPermission("doctor.use")) {
            player.sendMessage(
                    Component.text("[HEAL] Cannot use this command")
                            .color(NamedTextColor.RED)
            );
            return false;
        }

        Component message = createClickableMessage(
                "&6&l[HEAL] Click to be Healed",
                "doctor healme"
        );

        if (args.length == 0) {
            player.sendMessage(message);
            return true;
        } else if (args.length == 1 && args[0].equalsIgnoreCase("healme")) {
            healPlayer(player);

            player.sendMessage(
                    Component.text("[HEAL] You've Been Healed")
                            .color(NamedTextColor.GREEN)
            );
            return true;
        }

        player.sendMessage(
                Component.text("[HEAL] Usage: /doctor")
                        .color(NamedTextColor.RED)
        );
        return false;
    }

    @NonNull
    private Component createClickableMessage(@NonNull String message, @NonNull String command) {
        Component text = deserializeText(message);

        return text.clickEvent(
                ClickEvent.clickEvent(
                        ClickEvent.Action.RUN_COMMAND,
                        "/" + command
                )
        );
    }

    @NonNull
    private Component deserializeText(@NonNull String text) {
        return LegacyComponentSerializer
                .legacy('&')
                .deserialize(text);
    }
}

private void healPlayer(@NonNull Player player) {
    if (player.getHealth() != 20.0D)
        player.setHealth(20.0D);
    else
        player.sendMessage(
                Component.text("You are already full health!")
                        .color(NamedTextColor.RED)
        );
}

Here is a valid YAML file:

YAML:
name: TestPlugin
version: '${version}'
main: me.mackaroni.testplugin.TestPlugin
api-version: '1.20'
authors: [mackaroni]
description: #Your project description

#every path is 2 spaces difference from the other
commands:
  doctor:
    aliases: heal
    description: Heal a player

Java:
@Override
public void onEnable() {
    /*
    Registering the command so the command would work in-game
    */
    getCommand("doctor").setExecutor(new HealCommand());
}
 
Last edited: