Solved Method not working cross-class

Discussion in 'Spigot Plugin Development' started by roofwobbler, Mar 29, 2020.

  1. I am a noob, I've only been learning java for a week. I transferred code from one class to another to make a method to make the code look a lot neater and make it easier to put error messages where they need to go but I need help because console threw this error. Intellij gives me no errors.
    Code (Text):
    [16:43:43 ERROR]: null
    org.bukkit.command.CommandException: Unhandled exception executing command 'ep' in plugin EndPortalSell v1.0
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:47) ~[Paper.jar:git-PaperSpigot-"4c7641d"]
        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:146) ~[Paper.jar:git-PaperSpigot-"4c7641d"]
        at org.bukkit.craftbukkit.v1_8_R3.CraftServer.dispatchCommand(CraftServer.java:666) ~[Paper.jar:git-PaperSpigot-"4c7641d"]
        at net.minecraft.server.v1_8_R3.PlayerConnection.handleCommand(PlayerConnection.java:1189) [Paper.jar:git-PaperSpigot-"4c7641d"]
        at net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java:1001) [Paper.jar:git-PaperSpigot-"4c7641d"]
        at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java:45) [Paper.jar:git-PaperSpigot-"4c7641d"]
        at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java:1) [Paper.jar:git-PaperSpigot-"4c7641d"]
        at net.minecraft.server.v1_8_R3.PlayerConnectionUtils$1.run(SourceFile:13) [Paper.jar:git-PaperSpigot-"4c7641d"]
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
        at net.minecraft.server.v1_8_R3.SystemUtils.a(SourceFile:44) [Paper.jar:git-PaperSpigot-"4c7641d"]
        at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:774) [Paper.jar:git-PaperSpigot-"4c7641d"]
        at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:378) [Paper.jar:git-PaperSpigot-"4c7641d"]
        at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:713) [Paper.jar:git-PaperSpigot-"4c7641d"]
        at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:616) [Paper.jar:git-PaperSpigot-"4c7641d"]
        at java.base/java.lang.Thread.run(Thread.java:830) [?:?]
    Caused by: java.lang.NullPointerException
        at com.roof.endportal.EndPortal.onCommand(EndPortal.java:131) ~[?:?]
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[Paper.jar:git-PaperSpigot-"4c7641d"]
        ... 15 more

    The method I am accessing:
    Code (Java):
    package com.roof.endportal;

    import org.bukkit.ChatColor;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.entity.ArmorStand;
    import org.bukkit.entity.EntityType;
    import org.bukkit.entity.Player;

    public class Util {

        private Main main;

        public Util(Main main) { this.main = main; }



        public void makeEndPortalPlayer(Player player) {
            Location loc = player.getLocation();

            loc.add(0, -2, 0);
            loc.getBlock().setType(Material.ENDER_PORTAL_FRAME);
            loc.add(0, 0, 1);
            loc.getBlock().setType(Material.ENDER_PORTAL_FRAME);
            loc.add(0, 0, 1);
            loc.getBlock().setType(Material.ENDER_PORTAL_FRAME);
            loc.add(0, 0, 1);
            loc.getBlock().setType(Material.ENDER_STONE);
            loc.add(-1, 0, 0);
            loc.getBlock().setType(Material.ENDER_PORTAL_FRAME);
            loc.add(-1, 0, 0);
            loc.getBlock().setType(Material.ENDER_PORTAL_FRAME);
            loc.add(-1, 0, 0);
            loc.getBlock().setType(Material.ENDER_PORTAL_FRAME);
            loc.add(-1, 0, 0);
            loc.getBlock().setType(Material.ENDER_STONE);
            loc.add(0, 0, -1);
            loc.getBlock().setType(Material.ENDER_PORTAL_FRAME);
            loc.add(0, 0, -1);
            loc.getBlock().setType(Material.ENDER_PORTAL_FRAME);
            loc.add(0, 0, -1);
            loc.getBlock().setType(Material.ENDER_PORTAL_FRAME);
            loc.add(0, 0, -1);
            loc.getBlock().setType(Material.ENDER_STONE);
            loc.add(1, 0, 0);
            loc.getBlock().setType(Material.ENDER_PORTAL_FRAME);
            loc.add(1, 0, 0);
            loc.getBlock().setType(Material.ENDER_PORTAL_FRAME);
            loc.add(1, 0, 0);
            loc.getBlock().setType(Material.ENDER_PORTAL_FRAME);
            loc.add(1, 0, 0);
            loc.getBlock().setType(Material.ENDER_STONE);
            loc.add(-1, 0, 1);
            loc.getBlock().setType(Material.ENDER_PORTAL);
            loc.add(0, 0, 1);
            loc.getBlock().setType(Material.ENDER_PORTAL);
            loc.add(0, 0, 1);
            loc.getBlock().setType(Material.ENDER_PORTAL);
            loc.add(-1, 0, 0);
            loc.getBlock().setType(Material.ENDER_PORTAL);
            loc.add(-1, 0, 0);
            loc.getBlock().setType(Material.ENDER_PORTAL);
            loc.add(0, 0, -1);
            loc.getBlock().setType(Material.ENDER_PORTAL);
            loc.add(1, 0, 0);
            loc.getBlock().setType(Material.ENDER_PORTAL);
            loc.add(0, 0, -1);
            loc.getBlock().setType(Material.ENDER_PORTAL);
            loc.add(-1, 0, 0);
            loc.getBlock().setType(Material.ENDER_PORTAL);
            loc.add(1, 0, 1);
            ArmorStand stand = (ArmorStand) player.getWorld().spawnEntity(loc, EntityType.ARMOR_STAND);
            main.endPortalLoc.add(loc);
            stand.setCustomNameVisible(true);
            stand.setCustomName(ChatColor.AQUA + "Drop your items in here to sell them!");
            stand.setVisible(false);
            stand.setGravity(false);
            stand.setCanPickupItems(false);
            player.sendMessage(ChatColor.AQUA + "You're ready to sell!");
        }
    }
    The class the method is accessed from:
    Code (Java):
     @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
            if (sender instanceof Player) {

                Player player = (Player) sender;

                if (args.length == 1 || args.length == 2 || args.length == 3 || args.length == 4 ) {

                    switch (args[0]) {
                        //create an end portal at that location for selling
                        case "create":
                            switch (args.length) {
                                case 2:
                                case 3:
                                case 4:
                                    String x1 = args[1];
                                    String y1 = args[2];
                                    String z1 = args[3];
                                    boolean numeric = true;

                                    try {
                                        @SuppressWarnings("unused")
                                        Double num = Double.parseDouble(x1);
                                        @SuppressWarnings("unused")
                                        Double num1 = Double.parseDouble(y1);
                                        @SuppressWarnings("unused")
                                        Double num2 = Double.parseDouble(z1);
                                    } catch (NumberFormatException e) {
                                        numeric = false;
                                    }

                                    if(numeric) {
                                        Double x = Double.parseDouble(x1);
                                        Double y = Double.parseDouble(y1);
                                        Double z = Double.parseDouble(z1);

                                        Location loc = new Location(player.getWorld(), x, y, z);



                                        //Make end portal with cords.
                                    }
                                    break;
                                case 1:
                                    Util.makeEndPortalPlayer(player);

                                    break;
                                default:
                                    player.sendMessage(ChatColor.RED +"Usage: /endportal create (x) (y) (z) or /endportal create");
                                    break;
     
  2. Send line 131 here... because it is reading null
     
  3. also
    can just be
     
  4. Line 131 is where I access the method makeEndPortalPlayer(player)
     
  5. What I think is wrong here is that you are trying to access the method as if it's a static method. You would first need to do
    Code (Java):
    Util util = new Util(main);
    and then you can do
    Code (Text):
    util.makeEndPortalPlayer(player);
     
    • Agree Agree x 1
  6. When I do it like that it gives me an error saying to make makeEndPortalPlayer a static method then my main variable doesn't work in the Util class. It wants me to make the main static and then I can't access my List I have in main.
     
  7. I figured out a solution by moving the method to the main class but I'd like it to not be a permanent solution.
     
  8. Can we see all relevant code and what you are exactly trying to achieve, it shouldn't tell you to make it static if you did it right. (just a bit confused what you are doing)
     
  9. All of the relevant code is in my original post and I get this error when I try to access the method makeEndPortalPlayer (which is in the Util class) from the EndPortal class "Non-static method 'makeEndPortalPlayer(org.bukkit.entity.Player)' cannot be referenced from a static context"
     
  10. Post the code that you are using with what I put in my previous response. If you instantiate the class, it shouldn't say that you are trying to access it from a static context.
     
  11. I tried it like this
    Code (Java):
        private Util util;

        public EndPortal(Util util) { this.util = util; }
    and your way and they both gave me the same error
    It also gave me the error "Value 'main' is always 'null'"
     
  12. Try doing this instead

    Code (Java):
    private Main main;
    private Util util;

    public EndPortal(Main main) {
         this.main = main;
         this.util = new Util(main);
    }
     
  13. Let's unpack some stuff here:
    Main is not a suitable name for the main-class. Make something that is more descriptive, like the name of the plugin you are developing.
    Utility-classes usually only contain static methods and a private constructor, so that you cannot instantiate it (take a look at java.lang.Math, for example). If you wish to use a Singleton instead, rename that class into something more meaningful, like EndPortalBuilder (just as an example).
    You should really use a loop here.
    An armor-stand cannot pickup items. This whole thing is a little bit of a mess.
    There's a lot going on here. First of all, you get args 1 through 3, even if the length of the arguments-array is only 2 or 3. So if I were to type /enderportal create 1, it would throw an ArrayIndexOutOfBoundsException. Then, you are parsing the numbers, just to ignore what you have parsed and parsing them again.
    Also, a switch with only one argument (your switch on args[0]) should never really happen, use a simple if-statement here and preferably ignore the casing (String#equalsIgnoreCase(String)). Now for your error.
    As mentioned above, you are trying to do two things. Using Util util = new Util(main), you are creating an Object (big plus on that dependency injection thou). However, you are accessing the methods statically. That means you are accessing a method that belongs to the class, not the object. This is a really important difference that comes with a lot of side-effects. There can be multiple objects, but there can only be one class, for example. This means that the class will never know any of the properties that belong to objects. There are multiple solutions:
    1) Static access to your plugin
    (This is one of the worse ways you could do this) Since your plugin is a singleton, you can get a handle to that using JavaPlugin#getPlugin(). You can now make your utility-method static using the instance of your plugin
    2) Provide your plugin as an argument to the constructor as well
    Simply this:
    Code (Java):
    public static void buildPortal(Player player, Plugin plugin) {
        //...
    }
    3) Use the singleton-pattern (but then please rename that class)
    Code (Java):
    EndPortalBuilder builder = new EndPortalBuilder(plugin);
    //...
    builder.buildPortal(player);
    You'll need to be careful about how you handle that since you ideally only want to have one and only one instance of that class.
     
    #13 Schottky, Mar 30, 2020
    Last edited: Mar 30, 2020
  14. Thanks for the help!