NullPointerException

Discussion in 'Plugin Development' started by VenamousV, Oct 14, 2014.

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

    VenamousV

    The plugin I am trying to make saves a few things about a player into a config and it also has a chat editor. When I try to chat, or even login I get a NullPointerException error on my lines of codes that call my configs. Could someone please tell me why?
    Main Class(yet to have any errors):
    Code:java
    1. package com.VenamousV.kingdoms;
    2.  
    3. import java.io.File;
    4. import java.io.IOException;
    5. import java.io.InputStreamReader;
    6. import java.io.Reader;
    7. import java.io.UnsupportedEncodingException;
    8. import java.util.logging.Level;
    9. import java.util.logging.Logger;
    10.  
    11. import org.bukkit.command.Command;
    12. import org.bukkit.command.CommandSender;
    13. import org.bukkit.configuration.file.FileConfiguration;
    14. import org.bukkit.configuration.file.YamlConfiguration;
    15. import org.bukkit.entity.Player;
    16. import org.bukkit.event.Listener;
    17. import org.bukkit.plugin.PluginDescriptionFile;
    18. import org.bukkit.plugin.java.JavaPlugin;
    19.  
    20. public class Kingdoms extends JavaPlugin implements Listener{
    21.  
    22. public final Logger logger = Logger.getLogger("Minecraft");
    23. public static Kingdoms plugin;
    24.  
    25.  
    26. //
    27. //Player Config START
    28. //
    29. public FileConfiguration playerConfig = null;
    30. public File customPlayerFile = null;
    31. public void reloadPlayerConfig() throws UnsupportedEncodingException {
    32. if (customPlayerFile == null) {
    33. customPlayerFile = new File(getDataFolder(), "Players.yml");
    34. }
    35. playerConfig = YamlConfiguration.loadConfiguration(customPlayerFile);
    36.  
    37. // Look for defaults in the jar
    38. Reader defConfigStream = new InputStreamReader(this.getResource("Players.yml"), "UTF8");
    39. if (defConfigStream != null) {
    40. YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
    41. playerConfig.setDefaults(defConfig);
    42. }
    43. }
    44. public FileConfiguration getPlayerConfig() {
    45. if (playerConfig == null) {
    46. try {
    47. reloadPlayerConfig();
    48. // TODO Auto-generated catch block
    49. e.printStackTrace();
    50. }
    51. }
    52. return playerConfig;
    53. }
    54. public void savePlayerConfig() {
    55. if (playerConfig == null || customPlayerFile == null) {
    56. return;
    57. }
    58. try {
    59. getPlayerConfig().save(customPlayerFile);
    60. } catch (IOException ex) {
    61. getLogger().log(Level.SEVERE, "Could not save config to " + customPlayerFile, ex);
    62. }
    63. }
    64. public void saveDefaultPlayerConfig() {
    65. if (customPlayerFile == null) {
    66. customPlayerFile = new File(getDataFolder(), "Players.yml");
    67. }
    68. if (!customPlayerFile.exists()) {
    69. plugin.saveResource("Players.yml", false);
    70. }
    71. }
    72. //
    73. //Player Config END
    74. //
    75. //
    76. //Chat Config START
    77. //
    78. public FileConfiguration chatConfig = null;
    79. public File customChatFile = null;
    80. public void reloadChatConfig() throws UnsupportedEncodingException {
    81. if (customChatFile == null) {
    82. customChatFile = new File(getDataFolder(), "Chat.yml");
    83. }
    84. chatConfig = YamlConfiguration.loadConfiguration(customChatFile);
    85.  
    86. // Look for defaults in the jar
    87. Reader defConfigStream = new InputStreamReader(this.getResource("Chat.yml"), "UTF8");
    88. if (defConfigStream != null) {
    89. YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
    90. chatConfig.setDefaults(defConfig);
    91. }
    92. }
    93. public FileConfiguration getChatConfig() {
    94. if (chatConfig == null) {
    95. try {
    96. reloadChatConfig();
    97. // TODO Auto-generated catch block
    98. e.printStackTrace();
    99. }
    100. }
    101. return chatConfig;
    102. }
    103. public void saveChatConfig() {
    104. if (chatConfig == null || customChatFile == null) {
    105. return;
    106. }
    107. try {
    108. getChatConfig().save(customChatFile);
    109. } catch (IOException ex) {
    110. getLogger().log(Level.SEVERE, "Could not save config to " + customChatFile, ex);
    111. }
    112. }
    113. public void saveDefaultChatConfig() {
    114. if (customChatFile == null) {
    115. customChatFile = new File(getDataFolder(), "Chat.yml");
    116. }
    117. if (!customChatFile.exists()) {
    118. plugin.saveResource("Chat.yml", false);
    119. }
    120. }
    121. //
    122. //Chat Config END
    123. //
    124.  
    125. @Override
    126. public void onEnable() {
    127. getServer().getPluginManager().registerEvents(this, this);
    128. getServer().getPluginManager().registerEvents(new Chat(), this);
    129. getServer().getPluginManager().registerEvents(new Login(), this);
    130. PluginDescriptionFile pdfFile = this.getDescription();
    131. this.logger.info(pdfFile.getName() + " Version " + pdfFile.getVersion() + " has been enabled!");
    132. customPlayerFile = new File(getDataFolder(), "Players.yml");
    133. playerConfig = YamlConfiguration.loadConfiguration(customPlayerFile);
    134. getPlayerConfig();
    135. savePlayerConfig();
    136. customChatFile = new File(getDataFolder(), "Chat.yml");
    137. chatConfig = YamlConfiguration.loadConfiguration(customChatFile);
    138. getChatConfig();
    139. saveChatConfig();
    140. }
    141.  
    142. @Override
    143. public void onDisable() {
    144. PluginDescriptionFile pdfFile = this.getDescription();
    145. this.logger.info(pdfFile.getName() + " has been disabled!");
    146. }
    147.  
    148. @Override
    149. public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
    150. Player player = (Player) sender;
    151. return false;
    152. }
    153.  
    154. }
    155.  


    Login Class(errors start on line: 22):
    Code:java
    1. package com.VenamousV.kingdoms;
    2.  
    3. import java.util.logging.Logger;
    4.  
    5. import org.bukkit.entity.Player;
    6. import org.bukkit.event.EventHandler;
    7. import org.bukkit.event.Listener;
    8. import org.bukkit.event.player.PlayerLoginEvent;
    9.  
    10. public class Login implements Listener {
    11. public final Logger logger = Logger.getLogger("Minecraft");
    12. private Kingdoms plugin;
    13.  
    14. public Login() {
    15. this.plugin = plugin;
    16. }
    17.  
    18. @EventHandler
    19. public void onLogin(PlayerLoginEvent e){
    20. Player p = e.getPlayer();
    21. if(p.getDisplayName() == p.getDisplayName()){
    22. plugin.getPlayerConfig().createSection(p.getDisplayName());
    23. plugin.savePlayerConfig();
    24. plugin.getPlayerConfig().createSection(p.getDisplayName()+".UUID");
    25. plugin.savePlayerConfig();
    26. plugin.getPlayerConfig().set(p.getDisplayName()+".UUID", p.getUniqueId());
    27. plugin.savePlayerConfig();
    28. plugin.getPlayerConfig().createSection(p.getDisplayName()+".Prefix");
    29. plugin.savePlayerConfig();
    30. plugin.getPlayerConfig().set(p.getDisplayName()+".Prefix", "");
    31. plugin.savePlayerConfig();
    32. plugin.getPlayerConfig().createSection(p.getDisplayName()+".Suffix");
    33. plugin.savePlayerConfig();
    34. plugin.getPlayerConfig().set(p.getDisplayName()+".Suffix", "");
    35. plugin.savePlayerConfig();
    36. plugin.getPlayerConfig().createSection(p.getDisplayName()+".Join Date");
    37. plugin.savePlayerConfig();
    38. plugin.getPlayerConfig().set(p.getDisplayName()+".Join Date", p.getFirstPlayed());
    39. plugin.savePlayerConfig();
    40. plugin.getPlayerConfig().createSection(p.getDisplayName()+".Last Played");
    41. plugin.savePlayerConfig();
    42. plugin.getPlayerConfig().set(p.getDisplayName()+".Last Played", p.getLastPlayed());
    43. plugin.savePlayerConfig();
    44. }else{
    45. if(!plugin.getPlayerConfig().contains(p.getDisplayName()+".UUID")){
    46. plugin.getPlayerConfig().createSection(p.getDisplayName()+".UUID");
    47. plugin.savePlayerConfig();
    48. plugin.getPlayerConfig().set(p.getDisplayName()+".UUID", p.getUniqueId());
    49. plugin.savePlayerConfig();
    50. }if(!plugin.getPlayerConfig().contains(p.getDisplayName()+".Prefix")){
    51. plugin.getPlayerConfig().createSection(p.getDisplayName()+".Prefix");
    52. plugin.savePlayerConfig();
    53. plugin.getPlayerConfig().set(p.getDisplayName()+".Prefix", "");
    54. plugin.savePlayerConfig();
    55. }if(!plugin.getPlayerConfig().contains(p.getDisplayName()+".Suffix")){
    56. plugin.getPlayerConfig().createSection(p.getDisplayName()+".Suffix");
    57. plugin.savePlayerConfig();
    58. plugin.getPlayerConfig().set(p.getDisplayName()+".Suffix", "");
    59. plugin.savePlayerConfig();
    60. }if(!plugin.getPlayerConfig().contains(p.getDisplayName()+".Join Date")){
    61. plugin.getPlayerConfig().createSection(p.getDisplayName()+".Join Date");
    62. plugin.savePlayerConfig();
    63. plugin.getPlayerConfig().set(p.getDisplayName()+".Join Date", p.getFirstPlayed());
    64. plugin.savePlayerConfig();
    65. }if(!plugin.getPlayerConfig().contains(p.getDisplayName()+".Last Played")){
    66. plugin.getPlayerConfig().createSection(p.getDisplayName()+".Last Played");
    67. plugin.savePlayerConfig();
    68. plugin.getPlayerConfig().set(p.getDisplayName()+".Last Played", p.getLastPlayed());
    69. plugin.savePlayerConfig();
    70. }
    71. }
    72. }
    73. }
    74.  


    Chat Class(errors start on line: 33):
    Code:java
    1. package com.VenamousV.kingdoms;
    2.  
    3. import java.io.File;
    4. import java.io.IOException;
    5. import java.io.InputStreamReader;
    6. import java.io.Reader;
    7. import java.io.UnsupportedEncodingException;
    8. import java.util.logging.Level;
    9. import java.util.logging.Logger;
    10.  
    11. import org.bukkit.ChatColor;
    12. import org.bukkit.configuration.file.FileConfiguration;
    13. import org.bukkit.configuration.file.YamlConfiguration;
    14. import org.bukkit.entity.Player;
    15. import org.bukkit.event.EventHandler;
    16. import org.bukkit.event.Listener;
    17. import org.bukkit.event.player.AsyncPlayerChatEvent;
    18. import org.bukkit.plugin.PluginDescriptionFile;
    19. import org.bukkit.plugin.java.JavaPlugin;
    20.  
    21. public class Chat implements Listener {
    22.  
    23. public final Logger logger = Logger.getLogger("Minecraft");
    24. private Kingdoms plugin;
    25.  
    26. public Chat() {
    27. this.plugin = plugin;
    28. }
    29.  
    30. @EventHandler
    31. public void onChat(AsyncPlayerChatEvent e){
    32. Player p = e.getPlayer();
    33. String prefix = plugin.getPlayerConfig().getString(p.getName()+".Prefix");
    34.  
    35. e.setFormat(plugin.getChatConfig().getString("Format").replaceAll("'", "").replaceAll("&0", ChatColor.BLACK + "").replaceAll("&1", ChatColor.DARK_BLUE + "").replaceAll("&2", ChatColor.DARK_GREEN + "").replaceAll("&3", ChatColor.DARK_AQUA + "").replaceAll("&4", ChatColor.DARK_RED + "").replaceAll("&5", ChatColor.DARK_PURPLE + "").replaceAll("&6", ChatColor.GOLD + "").replaceAll("&7", ChatColor.GRAY + "").replaceAll("&8", ChatColor.DARK_GRAY + "").replaceAll("&9", ChatColor.BLUE + "").replaceAll("&a", ChatColor.GREEN + "").replaceAll("&b", ChatColor.AQUA + "").replaceAll("&c", ChatColor.RED + "").replaceAll("&d", ChatColor.LIGHT_PURPLE + "").replaceAll("&e", ChatColor.YELLOW + "").replaceAll("&f", ChatColor.WHITE + "").replaceAll("&r", ChatColor.RESET + "").replaceAll("&l", ChatColor.BOLD + "").replaceAll("&n", ChatColor.UNDERLINE + "").replaceAll("&o", ChatColor.ITALIC + "").replaceAll("&k", ChatColor.MAGIC + "").replaceAll("&m", ChatColor.STRIKETHROUGH + "").replaceAll("%prefix%", prefix + "") + "");
    36. }
    37.  
    38. }
    39.  
     
  2. Offline

    Watto

    You aren't initializing the plugin variable so it's null.
     
  3. Offline

    VenamousV

    How do I do that? Watto
     
  4. Offline

    Watto

    VenamousV

    Code:java
    1. getServer().getPluginManager().registerEvents(new Chat(this), this);
    2. getServer().getPluginManager().registerEvents(new Login(this), this);


    When you create Login and Chat event assign the plugin to the constructor.

    Code:java
    1. public Login(Kingdoms pl) {
    2. this.plugin = pl;
    3. }
    4.  
    5. public Chat(Kingdoms pl) {
    6. this.plugin = pl;
    7. }


    Then assign plugin to the main plugin class.

    Hope that makes sense. I'm not great at explaining things xD
     
  5. Offline

    VenamousV

    Okay that worked great. Now I am having a problem with line 35 of the Chat Class
    Code:java
    1. e.setFormat(plugin.getChatConfig().getString("Format").replaceAll("'", "").replaceAll("&0", ChatColor.BLACK + "").replaceAll("&1", ChatColor.DARK_BLUE + "").replaceAll("&2", ChatColor.DARK_GREEN + "").replaceAll("&3", ChatColor.DARK_AQUA + "").replaceAll("&4", ChatColor.DARK_RED + "").replaceAll("&5", ChatColor.DARK_PURPLE + "").replaceAll("&6", ChatColor.GOLD + "").replaceAll("&7", ChatColor.GRAY + "").replaceAll("&8", ChatColor.DARK_GRAY + "").replaceAll("&9", ChatColor.BLUE + "").replaceAll("&a", ChatColor.GREEN + "").replaceAll("&b", ChatColor.AQUA + "").replaceAll("&c", ChatColor.RED + "").replaceAll("&d", ChatColor.LIGHT_PURPLE + "").replaceAll("&e", ChatColor.YELLOW + "").replaceAll("&f", ChatColor.WHITE + "").replaceAll("&r", ChatColor.RESET + "").replaceAll("&l", ChatColor.BOLD + "").replaceAll("&n", ChatColor.UNDERLINE + "").replaceAll("&o", ChatColor.ITALIC + "").replaceAll("&k", ChatColor.MAGIC + "").replaceAll("&m", ChatColor.STRIKETHROUGH + "").replaceAll("%prefix%", prefix + "") + "");

    The error is still a nullPointerException Watto
     
  6. Offline

    teej107

    VenamousV Remove all your static declarations.

    EDIT: And get your own logger.
     
  7. VenamousV if you are calling a method with a parameter as a methodcall from another class, you should insert null safety. this would look like this in your login class:
    Code:java
    1. if(plugin!=null){
    2. PlayerConfig config = plugin.getPlayerConfig();
    3. if(config!=null&&p!=null){
    4. String displayName = p.getDisplayName();
    5. if(displayName!=null&&!displayName.equals(""){
    6. config.createSection(displayName);
    7. // execute rest of your code
    8. }
    9. else
    10. System.out.println("Handle no displayName");
    11. }
    12. else
    13. System.out.println("Handle no config or no player");
    14. }

    Do the same in your onChat method. Check if the plugin exists, if the playerConfig exists and if the players name exists.

    INFO: A NullpointerException is thrown, if you call a method on an object which is null. for example:
    Code:java
    1. String normalObject = "hey, im an object";
    2. String nullPointer = null;
    3. normalObject.equals("test"); // will return false and work fine
    4. nullPointer.equals("test"); // will throw a NullpointerException, because you call a method on null

    If you call the method getPlayerConfig() the method could return null. if you call then getString("parameter") on it, you are calling this method on null and so you will get thrown a NullpointerException. Like in the example i showed you. This is why you should include null checks to make your code "null safe"
     
  8. Offline

    teej107

    Shmobi null checks are nice but they can prevent needed code from executing. NPE is occurring from an error on the developers part.
     
  9. Offline

    Watto

    VenamousV

    Awesome :) hmm.. i'm not sure about this one does your .yml get created / read correctly?
     
  10. teej107 null safety is a) very important and b) the target is not to force the code to run, the target should be to handle exceptions like there is no config for the specific player etc. so null checks would be the solution which should be used, isn't it?
     
  11. Offline

    Watto

    VenamousV

    Also as a side note i would suggest that with your extremely large '.replaceAll' list you do a new line after each replace so it would look something like this

    Code:java
    1. e.setFormat(plugin.getChatConfig().getString("Format").replaceAll("'", "").replaceAll("&0", ChatColor.BLACK + "")
    2. .replaceAll("&1", ChatColor.DARK_BLUE + "")
    3. .replaceAll("&2", ChatColor.DARK_GREEN + "")
    4. .replaceAll("&3", ChatColor.DARK_AQUA + "")
    5. .replaceAll("&4", ChatColor.DARK_RED + "")
    6. .replaceAll("&5", ChatColor.DARK_PURPLE + "")
    7. .replaceAll("&6", ChatColor.GOLD + "");


    I'm not sure if that translated correctly but it makes your code more readable and easier to edit.
     
  12. Offline

    teej107

    Shmobi Yes, but a null check shouldn't be used on an un-initialized variable.
     
  13. Offline

    VenamousV

    Actually, looking at my configs again, it is resetting them every time I reload the server, I don't know if that'd make a difference. Watto
     
  14. Offline

    Watto

    VenamousV

    As long as you're loading them correctly you should be fine..
    I've only very basically gone into configs so i can't say anything about your code but there does seem to be a lot of code in the creation of the YAML files..

    For example i can create a config file which creates when it doesn't exists which loads with default and if it exists it reads the new config files with the following lines.

    Code:
    //Code to create default config getConfig().addDefault("key", "value");
    getConfig().options.copyDefaults(true);
    saveConfig();
     
    //Code to get config
    String value = getConfig().getString("key");
     
    
    Again though i'm a huge noob when it comes to config files and i haven't really read your configuration set-up code that much.
     
  15. teej107 it is initialized, because the method must return something. if you initialize a variable with null, it's still initialized. and the method must return either a object or null, so they are all initialized. this is the safest and easiest way to do this. the nullpointer exception must not be a error of the developer, this is the biggest shit i ve ever heard!! for example if a player joins who has no config and you try to load it, you wont find it and return null. then you should look if its null -> create new config. Other example, you loop through a list and search vor an object but there is none like this, you will get null returned. then you have to check if it is null and insert the object into the list if it is null or you must handle somehow that the object is not in the list. npe's are often errors of the developers, but not always. and in this case i would say, that it happens, because there is no config for this player.
     
  16. Offline

    VenamousV

    Those are just custom configs so I can have more than one, I used that code for every plugin I've made so I don't think it is that. Watto
     
  17. Offline

    Watto

    VenamousV

    Trying doing what i said earlier with putting '.replaceAll' on a new line and see if the stack trace line number changes. It might not even be your config loading (hopefully)
     
  18. Offline

    teej107

    Shmobi
    Uninitialized variables are still null. I don't think you understand where the error is coming from. The issue is not the config, it is the class where he is getting it from. If the OP posted a stacktrace, you would see where it is coming from. I know where the error is coming from because his code looks like the generic bad youtube tutorial code.

    EDIT: Turns out the problem I was talking about was already fixed by the OP. My suggestions were directed toward his first problem and I didn't realize he had it fixed :p
     
  19. Offline

    VenamousV

    Omg, the whole time I forgot to make sure that the "Format" section on my ChatConfig was created... It all works now, thank you for all the help! Watto
     
  20. Offline

    Watto

    VenamousV

    Haha yeah Java can be very unforgiving :p
    All good and have fun with your plugin developing :)
     
  21. teej107 i guessed that there are 2 different nullpointer exceptions thrown. one is thrown in class a on line 22 and the other one in class b on line *im to lazy to look again but you can read it in his first post*. this is how i understood his question and this is why i thought, that the nullpointer exception is thrown because any method there returns null because there is no config. if you look at those both lines, he is trying to load a playerconfig, so i thought there is just no config he can load and thats why he gets it
     
  22. Offline

    teej107

    You were talking about the current nullpointer but I apparently missed the post where he fixed the one I was talking about.
     
Thread Status:
Not open for further replies.

Share This Page