Solved [1.12.2-R0.1-SNAPSHOT] Problem with ConfigurationSection#getConfigurationSection

Discussion in 'Spigot Plugin Development' started by JacobTDC, Jun 11, 2018.

  1. Whenever I try to use ConfigurationSection#getConfigurationSection on a private variable, it throws an error, and I have no clue why it is happening. IntelliJ finds no problems with the code, and neither can I. Does anybody know how to fix this?

    Also, any optimizations and pointers would be GREATLY appreciated, as I'm still new to Java...
    (I would code a server from scratch in JavaScript, but the protocol is just too complicated...)

    I have shortened the code to the part where the error happens.
    Code (Java):

    public class TNTLabsBossBars implements org.bukkit.event.Listener {
        private static Server server = Bukkit.getServer();
        private static Plugin plugin = server.getPluginManager().getPlugin("TNTLabs");
        private static FileConfiguration config = plugin.getConfig();
        private static ConfigurationSection bossBarsConfig = config.getConfigurationSection("boss-bars");

        private Map<String,BossBar> BossBars = new HashMap<String,BossBar>();
        private Map<String,Set<String>> BossBarsWorlds;
        private Map<String,List<Map<String,String>>> BossBarSettings;

        public TNTLabsBossBars() {
            server.getPluginManager().registerEvents(this, plugin);
            initializeBossBars();
        }

        public void initializeBossBars () {
            // Remove all players from BossBars
            for (BossBar bossBar : BossBars.values()) {
                bossBar.removeAll();
            }

            // Reset all BossBar settings
            BossBars = new HashMap<>();
            BossBarsWorlds = new HashMap<>();
            BossBarSettings = new HashMap<>();

            // Perform action for every BossBar setting
            for (String name : bossBarsConfig.getKeys(false)) {
                Bukkit.getLogger().info(name);

                // Load and set this BossBar's settings
                BossBarSettings.put(name, new ArrayList<Map<String,String>>());
                // VVVVV ERROR HAPPENS HERE!!! VVVVV
                for(Integer i = 1; i <= bossBarsConfig.getConfigurationSection(name).getConfigurationSection("bars").getKeys(false).size(); i++) {
                    ConfigurationSection barSetting = bossBarsConfig.getConfigurationSection(name).getConfigurationSection("bars").getConfigurationSection(i.toString());
                    Map<String,String> barSettingMap = new HashMap<>();
                    barSettingMap.put("title", ChatColor.translateAlternateColorCodes('&', barSetting.getString("title")));
                    barSettingMap.put("color", barSetting.getString("color"));
                    barSettingMap.put("progress", barSetting.getString("percent"));
                    barSettingMap.put("style", barSetting.getString("segments"));
                    BossBarSettings.get(name).add(barSettingMap);
                }

                // Create BossBars
                Map<String,String> barSettingMap = BossBarSettings.get(name).get(0);
                BossBar bossBar = server.createBossBar(barSettingMap.get("title"), BarColor.valueOf(barSettingMap.get("color")), BarStyle.valueOf(barSettingMap.get("style")));
                bossBar.setProgress( new Double(barSettingMap.get("progress")) / 100 );
                BossBars.put(name, bossBar);

                // Set BossBarWorlds
                List<String> bossBarWorlds = bossBarsConfig.getConfigurationSection(name).getStringList("worlds");
                for (String world : bossBarWorlds) {
                    if (BossBarsWorlds.containsKey(world)) BossBarsWorlds.get(world).add(name);
                    else BossBarsWorlds.put(world, new HashSet<String>(){{add(name);}});
                }
            }
        }
    }
     
    config.yml:
    Code (YAML):

    boss-bars
    :
     # The name of the bar.
      bar1
    :
       # A list of worlds that this bar should be seen in.
        worlds
    :
         - world
        bars
    :
          1
    :
           # Title of the bar.
            title
    : "&dWelcome to &cThe TNT Labs&d!"
            # For colors, see https://hub.spigotmc.org/javadocs/spigot/org/bukkit/boss/BarColor.html
            color
    : RED
            # Percentage of the bar that should be filled.
            percent
    : 50
            # For segments, see https://hub.spigotmc.org/javadocs/spigot/org/bukkit/boss/BarStyle.html
            segments
    : SOLID
            # The amount of time (in ticks) this bar should be displayed before moving to the next one.
            display-time
    : 100
          2
    :
            title
    : "&oThanks for joining us!"
            color
    : RED
            percent
    : 100
            segments
    : SOLID
            display-time
    : 100
     
    stacktrace:
    Code (Error):

    java.lang.NullPointerException: null
    at net.thetntlabs.main.BossBars.TNTLabsBossBars.initializeBossBars(TNTLabsBossBars.java:#) ~[?:?]
    at net.thetntlabs.main.BossBars.TNTLabsBossBars.<init>(TNTLabsBossBars.java:#) ~[?:?]
     
     
    #1 JacobTDC, Jun 11, 2018
    Last edited: Jun 16, 2018
  2. java.lang.NullPointerException: null
    It's throwing an NPE here bossBarsConfig.getConfigurationSection(name).getConfigurationSection("bars")
    which one of these is causing the NPE *shrug* you could do a test for both of these to find out
     
    • Agree Agree x 1
  3. For a case like this, I'd recommend using one of intellij's features (Not sure if you'll be able to make it work with a hosting service).
    To start a standard minecraft server, you can type "java -jar server.jar" to launch it. You can access the server WHILE it is running through this:
    java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=[Open port, I use 5005] -jar server.jar
    Next, in Intellij, up by your "run" and "debug" buttons, you'll find a drop down:
    upload_2018-6-11_14-8-30.png
    (Mine currently says SpigotServer because I've already set it up)
    Press this. Then select "edit configurations."
    Hit the green plus in the upper left, and go down the list until you find the option called "remote"
    Once created, name it to something, and you'll find the same text selection as I provided above (minus the java -jar whatnot).
    make sure the ports are the same, and press apply.
    Now, whenever your server is running, you can press your little green dubug button there and it will hook into your server! (Make sure to place a break point).
    you can press F8 by default to move onto the next line, each line will spit out its output to the side in italics. Once you've gathered the information you need, press F9 to allow the server to continue.
    (As a side note, by default you only have 60 seconds before the server times out. There's a setting in spigot.yml to change this.)
     
    • Informative Informative x 2
  4. Neither of these should be throwing an error. I've checked, and "name" equals "bar1" and "boss-bars.bar1.bars" is not null.
     
  5. private static ConfigurationSection bossBarsConfig = config.getConfigurationSection("boss-bars");
    this is null. youre getting the configuration section before the config has been loaded. see dependency injection.
     
  6. New development: It's loading fine, I can run config.getString("boss-bars.bar1.bars.1.title") and it returns "&dWelcome to &cThe TNT Labs&d!", but config.getConfigurationSection("boss-bars").getConfigurationSection("bar1").getConfigurationSection("bars") returns a null object. Is... that supposed to happen???
     
  7. The implication of a static memory modifier is that
    1. It is a class variable - unbounded by instance
    2. It will be fetched first
    You should not be using static variables here, and passing them through using dependency injection would be fine.

    Comment: If you really need the values to be fetched, assign it within the constructor. Else, I recommend fetching configuration values only when you need it.
     
  8. So, would private FileConfiguration config = server.getPluginManager().getPlugin("TNTLabs").getConfig() work?
    I'm still a little new to Java (but I have experience in other coding languages)...
     
  9. Wait, NVM, not even Bukkit.getServer().getPluginManager().getPlugin("TNTLabs").getConfigurationSection("boss-bars." + name + ".bars").getKeys(false) works...
     
  10. That's weird... config.getConfigurationSection("boss-bars").getConfigurationSection("bar1").getKeys(false).toString() throws an error while config.getConfigurationSection("boss-bars").getConfigurationSection("bar1").toString() doesn't...
     
  11. I found the problem. Apparently, numbers don't work as keys in a config.yml...
    You'd think I'd figure that one out sooner... XD
     
    #11 JacobTDC, Jun 16, 2018
    Last edited: Jun 16, 2018

Share This Page