Solved Arbitrary NPE

Discussion in 'Plugin Development' started by Compressions, Dec 30, 2013.

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

    Compressions

    Usually, I can avoid running into NullPointerExceptions, but randomly, to my dismay, one appeared in the console, stopping my plugin from loading properly. The exception points to this snippet of code, specifically to the commented line. I have an example of what the config looks like, and any classes that possibly connect to the line.

    NPE Snippet (open)

    Code:
        public static void loadArenas() {
            for(String name : NucleusFileIO.getNucleus().getConfigurationSection("arenas").getKeys(false)) { //NPE points to here
                NucleusArena arena = new NucleusArena(name);
                arenas.add(arena);
            }
        }


    NucleusFileIO Class(corresponds to JavaPlugin's implementation of FileConfiguration) (open)

    Code:
    public class NucleusFileIO {
     
        private static FileConfiguration nucleus = null;
        private static File nucleusFile = null;
     
        public static void loadNucleus() {
            if (nucleusFile == null) {
                nucleusFile = new File(Hegemon.getInstance().getDataFolder(), "nucleus.yml");
            }
            nucleus = YamlConfiguration.loadConfiguration(nucleusFile);
     
            // Look for defaults in the jar
            InputStream defConfigStream = Hegemon.getInstance().getResource("nucleus.yml");
            if (defConfigStream != null) {
                YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
                nucleus.setDefaults(defConfig);
            }
        }
     
        public static FileConfiguration getNucleus() {
            if (nucleus == null) {
                loadNucleus();
            }
            return nucleus;
        }
     
        public static void saveNucleus() {
            if (nucleus == null || nucleusFile == null) {
                return;
            }
            try {
                getNucleus().save(nucleusFile);
            } catch (IOException ex) {
                Hegemon.getInstance().getLogger().log(Level.SEVERE, "Could not save config to " + nucleusFile, ex);
            }
        }
     
    }
    


    nucleus.yml (open)
    Code:
    arenas:
        test:
            blue:
                spawn:
                    world: world
                    x: 10
                    y: 60
                    z: 10
                nucleus:
                    world: world
                    x: 5
                    y: 60
                    z: 5
            red:
                spawn:
                    world: world
                    x: 15
                    y: 60
                    z: 15
                nucleus:
                    world: world
                    x: 20
                    y: 60
                    z: 20

    NucleusArena Constructor (open)

    Code:
    public NucleusArena(String name) {
            this.name = name;
     
            FileConfiguration config = NucleusFileIO.getNucleus();
     
            World blueWorld = Bukkit.getWorld(config.getString("arenas." + name + ".blue.spawn.world"));
            int blueX = config.getInt("arenas." + name + ".blue.spawn.x");
            int blueY = config.getInt("arenas." + name + ".blue.spawn.y");
            int blueZ = config.getInt("arenas." + name + ".blue.spawn.z");
     
            this.blueSpawn = new Location(blueWorld, blueX, blueY, blueZ);
     
            World redWorld = Bukkit.getWorld(config.getString("arenas." + name + ".red.spawn.world"));
            int redX = config.getInt("arenas." + name + ".red.spawn.x");
            int redY = config.getInt("arenas." + name + ".red.spawn.y");
            int redZ = config.getInt("arenas." + name + ".red.spawn.z");
         
            this.redSpawn = new Location(redWorld, redX, redY, redZ);
     
            World blueNucleusWorld = Bukkit.getWorld(config.getString("arenas." + name + ".blue.nucleus.world"));
            int blueNucleusX = config.getInt("arenas." + name + ".blue.nucleus.x");
            int blueNucleusY = config.getInt("arenas." + name + ".blue.nucleus.y");
            int blueNucleusZ = config.getInt("arenas." + name + ".blue.nucleus.z");
     
            this.blueNucleus = blueNucleusWorld.getBlockAt(blueNucleusX, blueNucleusY, blueNucleusZ);
     
            World redNucleusWorld = Bukkit.getWorld(config.getString("arenas." + name + ".red.nucleus.world"));
            int redNucleusX = config.getInt("arenas." + name + ".red.nucleus.x");
            int redNucleusY = config.getInt("arenas." + name + ".red.nucleus.y");
            int redNucleusZ = config.getInt("arenas." + name + ".red.nucleus.z");
         
            this.redNucleus = redNucleusWorld.getBlockAt(redNucleusX, redNucleusY, redNucleusZ);
     
        }


    onEnable(where it's called) (open)

    Code:
        private static Hegemon instance;
     
        public void onEnable() {
            instance = this;
            KitsFileIO.loadKits();
            KitsFileIO.deserializeKits();
            NucleusFileIO.loadNucleus();
            NucleusArenaUtils.loadArenas();
            getCommand("nucleus").setExecutor(new NucleusCommand());
            getServer().getPluginManager().registerEvents(new NucleusListener(), this);
        }
     
  2. Offline

    Tirelessly

    Things that could possibly be null: getNucleus, getConfigurationSection("arenas")

    Use print statements to find out which of those is returning null.
     
  3. Offline

    Ronbo

    Compressions
    When I run into errors like these (where you have a bunch of method calls on one line), I find that the best way to pinpoint the issue is to split it up into multiple lines. Once you figure out exactly what is null, it should be an easy fix.
     
  4. Offline

    Compressions

Thread Status:
Not open for further replies.

Share This Page