Solved Error getting file in custom config

Discussion in 'Spigot Plugin Development' started by TheGamerPlayz, May 20, 2016.

Thread Status:
Not open for further replies.
  1. I made a custom config, but i keep getting an NPE when i try to get the file. Can anyone see why?

    StackTrace
    Code (Text):

    [19:27:18 ERROR]: Error occurred while enabling FlagPvP v1.0 (Is it up to date?)
    java.lang.NullPointerException
            at FlagPvP.dataManager.getFile(dataManager.java:20) ~[?:?]
            at FlagPvP.dataManager.getData(dataManager.java:27) ~[?:?]
            at FlagPvP.Listeners.StartCount.<init>(StartCount.java:24) ~[?:?]
            at FlagPvP.Main.onEnable(Main.java:25) ~[?:?]
            at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:321) ~[spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:340) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:405) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at org.bukkit.craftbukkit.v1_8_R3.CraftServer.loadPlugin(CraftServer.java:357) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at org.bukkit.craftbukkit.v1_8_R3.CraftServer.enablePlugins(CraftServer.java:317) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.MinecraftServer.s(MinecraftServer.java:414) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.MinecraftServer.k(MinecraftServer.java:378) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.MinecraftServer.a(MinecraftServer.java:333) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.DedicatedServer.init(DedicatedServer.java:263) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:525) [spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_73]
     
    Manager
    Code (Text):

        package FlagPvP;

    import java.io.File;
    import java.io.IOException;

    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.configuration.file.YamlConfiguration;

    public class dataManager{
        private Main pl;
        public dataManager(Main pl){
            this.pl = pl;
        }
        File file;
        FileConfiguration fc;
        String FileName = "data.yml";
       
        public File getFile(){
            if(file == null)
                file = new File(pl.getDataFolder(), FileName);                    //Here is Line 20
            System.out.println(pl);
            System.out.println(file);
            return file;
        }
       
        public FileConfiguration getData(){
            fc = YamlConfiguration.loadConfiguration(getFile());                          //Here is line 27
            return fc;
        }
       
        public void saveData(){
            file = new File(pl.getDataFolder(), FileName);
            try{
                fc.save(getFile());
            } catch(IOException e){
                e.printStackTrace();
                System.out.println("[Economy] Attempting to fix error...");
                createData();
                saveData();
            }
        }
        public void createData(){
            if(!getFile().exists()){
                if(!pl.getDataFolder().exists()){
                    pl.getDataFolder().mkdirs();
                }
                pl.saveResource(FileName, false);
            }
        }
    }
     
     
  2. Your plugin instance is null. Check out where you instantiate your dataManager class.

    Side Note: It is a standard java convention to name your classes in upper camel case (LikeThis not likeThis)
     
  3. I use this to initialize it
    Code (Java):
     new dataManager(this);
    Edit: I always use it in the exact same way, and its only not working on this one
     
  4. Can you show me your main class? Maybe you are doing what someone else was doing the other day and creating a second instance using a reference to a plugin field?
     
  5. Code (Java):

    package FlagPvP;

    import java.io.File;

    import org.bukkit.Bukkit;
    import org.bukkit.event.Listener;
    import org.bukkit.plugin.Plugin;
    import org.bukkit.plugin.java.JavaPlugin;

    import FlagPvP.Commands.Locb;
    import FlagPvP.Commands.TPloc;
    import FlagPvP.Commands.blocktp;
    import FlagPvP.Commands.gamefinished;
    import FlagPvP.Listeners.BlockBurn;
    import FlagPvP.Listeners.StartCount;

    public class Main extends JavaPlugin{
        public static Plugin plugin;
        dataManager dm = new dataManager(this);
        public void onEnable(){
            plugin = this;
            new dataManager(this);
            dm.createData();
            config();
            registerEvents(this, new BlockBurn(this), new StartCount(this));
            registerCommands();
        }
        public static void registerEvents(org.bukkit.plugin.Plugin plugin, Listener... listeners) {
            for (Listener listener : listeners){
                Bukkit.getServer().getPluginManager().registerEvents(listener, plugin);
            }
        }
        public void registerCommands(){
            getCommand("Locb").setExecutor(new Locb(this));
            getCommand("blocktp").setExecutor(new blocktp(this));
            getCommand("tploc").setExecutor(new TPloc(this));
            getCommand("finishedLoc").setExecutor(new gamefinished(this));
        }
        public static Plugin getPlugin(){
            return plugin;
        }
        public void config(){
            File file = new File(getDataFolder(), "config.yml");
            if(!file.exists())
                saveDefaultConfig();
        }
    }
     
     
  6. Ok so on line 25 we have
    Code (Text):
    registerEvents(this, new BlockBurn(this), new StartCount(this));
    which makes sense because the stacktrace said that the exception occurred inside the StartCount constructor. Can I check out that class as well?
     
  7. Sure
    Code (Java):

    package FlagPvP.Listeners;

    import java.util.HashMap;

    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Location;
    import org.bukkit.World;
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerMoveEvent;

    import FlagPvP.Main;
    import FlagPvP.dataManager;

    public class StartCount implements Listener{
        Main pl;
        public StartCount(Main pl){
            this.pl = pl;
        }
        dataManager dm = new dataManager(pl);
        FileConfiguration data = dm.getData();
        @EventHandler
        public void onPlayerMove(PlayerMoveEvent event){
            Player p =  event.getPlayer();
            if(p.getWorld().toString() == pl.getConfig().getString("WorldName")){
                HashMap<Player, Long> map = new HashMap<Player, Long>();
                if(!map.containsKey(p)){
                    map.put(p, System.currentTimeMillis());
                }
                long time = map.get(p) + pl.getConfig().getInt("GameLength");
                long current = System.currentTimeMillis();
                if(time > current){
                    Bukkit.broadcastMessage(
                            ChatColor.GOLD + "[" + ChatColor.RED + "FlagWars" + ChatColor.GOLD + "]" +
                            ChatColor.AQUA + pl.getConfig().getString("BlueWinMessage"));
                } else if(time + 5000 > current){
                    pl.saveConfig();
                    String coord = data.get("Location").toString();
                    String[] coords = coord.split(", ");
                    World world = (World) pl.getConfig().get("World");
                    int x = Integer.parseInt(coords[0]);
                    int y = Integer.parseInt(coords[1]);
                    int z = Integer.parseInt(coords[2]);
                    Location loc = new Location(world, x, y, z);
                    for(Player players : Bukkit.getOnlinePlayers()){
                        players.teleport(loc);
                        players.getInventory().clear();
                    }
                }
            }
        }
    }
     
     
  8. Change this
    Code (Text):

        dataManager dm = new dataManager(this);
        public void onEnable(){
            plugin = this;
            new dataManager(this);
     
    to this:
    Code (Text):

        dataManager dm;
        public void onEnable(){
            plugin = this;
            dm = new dataManager(this);
     
     
  9. Ok we have found our problem!
    Code (Text):
        Main pl;
        public StartCount(Main pl){
            this.pl = pl;
        }
        dataManager dm = new dataManager(pl);
    The field "dm" is assigned before the constructor is called. The "pl" field is not assigned until the constructor is called. This means that it remains null until construction time. Therefor "dm" has been constructed with a null reference for the plugin argument.

    Also some refactoring that @NinjaStix mentioned should be carried out along with considering using the already constructed instance of "dataManager" that you create in your Main class instead of making a new one every time you need it.
     
    • Agree Agree x 2
  10. Ok thanks it is working just fine now, any chance you know how to get the material name of a block?
    When i have it print out into chat it is correct but when i store it in a config I get this.
    Code (Text):
    !!org.bukkit.Material 'REDSTONE_BLOCK'
    I used this to get it
    Code (Text):
     Material block = player.getLocation().getBlock().getRelative(BlockFace.DOWN).getType();
     
  11. That is the name of the class that is serialized so that when you are deserializing it the parser knows what to instantiate or what enum constant to resolve. I would just save the Material#name() and keep your config a bit cleaner by saving a string instead of a Material since it is very easy to look up the material yourself later with Material.valueOf(stringFromConfig).
     
    • Useful Useful x 1
  12. Oh ok thanks for all the help
     
    • Like Like x 1
Thread Status:
Not open for further replies.