Solved A wild java.lang.ClassCastException appeared...

Discussion in 'Plugin Development' started by bramhaag, Aug 20, 2014.

Thread Status:
Not open for further replies.
  1. Hi,

    I'm making a minigame, but I have a problem... A java.lang.ClassCastException appears on Line 32 in my Sign manager. And yes, I extended JavaPlugin in my Main class!

    Error:
    Code:
    [20:28:15 ERROR]: Error occurred while enabling Titanfall v0.6-ALPHA_BUILD (Is i
    t up to date?)
    java.lang.ClassCastException: org.bukkit.craftbukkit.v1_7_R3.block.CraftBlockSta
    te cannot be cast to org.bukkit.block.Sign
            at ph.url.techzone.Titanfall.SignManager.<init>(SignManager.java:32) ~[?
    :?]
            at ph.url.techzone.Titanfall.Main.onEnable(Main.java:47) ~[?:?]
    SignManager Line 32:
    Code:java
    1. Sign s = (Sign) loc.getBlock().getState();


    onEnable line 47:
    Code:java
    1. pm.registerEvents(new SignManager(), this);
    2.  
    3. //pm variable
    4. PluginManager pm = Bukkit.getServer().getPluginManager();


    Full SignManager class:
    Code:java
    1. package ph.url.techzone.Titanfall;
    2.  
    3. import java.util.ArrayList;
    4. import java.util.HashMap;
    5.  
    6. import org.bukkit.ChatColor;
    7. import org.bukkit.Location;
    8. import org.bukkit.block.Sign;
    9. import org.bukkit.configuration.ConfigurationSection;
    10. import org.bukkit.event.EventHandler;
    11. import org.bukkit.event.Listener;
    12. import org.bukkit.event.block.Action;
    13. import org.bukkit.event.block.SignChangeEvent;
    14. import org.bukkit.event.player.PlayerInteractEvent;
    15.  
    16. import ph.url.techzone.Titanfall.Arena.ArenaState;
    17.  
    18. public class SignManager implements Listener {
    19.  
    20. private static HashMap<Sign, Integer> signs = new HashMap<Sign, Integer>();
    21.  
    22. public SignManager() {
    23.  
    24. if (!SettingsManager.getLobbySigns().contains("signs")) {
    25. SettingsManager.getLobbySigns().createConfigurationSection("signs");
    26. }
    27.  
    28. for (String str : SettingsManager.getLobbySigns().<ConfigurationSection>get("signs").getKeys(true)) {
    29. ConfigurationSection section = SettingsManager.getLobbySigns().get("signs." + str);
    30.  
    31. Location loc = LocationUtil.locationFromConfig(section.getConfigurationSection("location"), false);
    32. Sign s = (Sign) loc.getBlock().getState();
    33.  
    34. signs.put(s, section.getInt("arenaNumber"));
    35. }
    36. }
    37.  
    38. public static ArrayList<Sign> getSigns(Arena a) {
    39. ArrayList<Sign> s = new ArrayList<Sign>();
    40.  
    41. for (Sign sign : signs.keySet()) {
    42. if (ArenaManager.getInstance().getArena(signs.get(sign)) == a) s.add(sign);
    43. }
    44.  
    45. return s;
    46. }
    47.  
    48.  
    49. @EventHandler
    50. public void onSignChange(SignChangeEvent e) {
    51. if (e.getLine(0).equalsIgnoreCase("[Titanfall]")) {
    52. int id;
    53. try { id = Integer.parseInt(e.getLine(1)); }
    54. catch (Exception ex) { e.getPlayer().sendMessage(Main.pre + ChatColor.RED + "That is not a valid arena number!"); return; }
    55.  
    56. Arena a = ArenaManager.getInstance().getArena(id);
    57. if (a == null) {
    58. e.getPlayer().sendMessage(Main.pre + "That is not a valid arena!");
    59. return;
    60. }
    61.  
    62. ConfigurationSection section = SettingsManager.getLobbySigns().createConfigurationSection("signs." + SettingsManager.getLobbySigns().<ConfigurationSection>get("signs").getKeys(true).size() + 1);
    63.  
    64. ConfigurationSection location = section.createSection("location");
    65. location.set("world", e.getBlock().getLocation().getWorld().getName());
    66. location.set("x", e.getBlock().getLocation().getX());
    67. location.set("y", e.getBlock().getLocation().getY());
    68. location.set("z", e.getBlock().getLocation().getZ());
    69.  
    70. section.set("arenaNumber", id);
    71.  
    72. signs.put((Sign) e.getBlock().getState(), a.getID());
    73.  
    74. e.setLine(0, ChatColor.LIGHT_PURPLE + "Titanfall");
    75. e.setLine(2, a.getCurrentPlayers() + "/" + SettingsManager.getArenas().get("arenas." + id + ".numPlayers") + " Players");
    76.  
    77. if (a.getState().equals(ArenaState.DISABLED)) {
    78. e.setLine(3, ChatColor.DARK_RED + "Disabled");
    79. }
    80. else if (a.getState().equals(ArenaState.WAITING)) {
    81. e.setLine(3,ChatColor.GREEN + "Waiting");
    82. }
    83. else if (a.getState().equals(ArenaState.COUNTING_DOWN)) {
    84. e.setLine(3, ChatColor.RED + "" + ChatColor.UNDERLINE + "Counting Down");
    85. }
    86. else if (a.getState().equals(ArenaState.STARTED)){
    87. e.setLine(3, ChatColor.DARK_AQUA + "Started");
    88. }
    89. else {
    90. e.setLine(3, ChatColor.RED + "Error");
    91. }
    92. }
    93. }
    94.  
    95. @EventHandler
    96. public void onPlayerInteract(PlayerInteractEvent e) {
    97. if (!(e.getAction() == Action.RIGHT_CLICK_AIR) && !(e.getAction() == Action.RIGHT_CLICK_BLOCK)) return;
    98.  
    99. if (e.getClickedBlock() == null || e.getClickedBlock().getState() == null) return;
    100.  
    101. if (e.getClickedBlock().getState() instanceof Sign) {
    102. Sign s = (Sign) e.getClickedBlock().getState();
    103. if (s.getLine(0).equalsIgnoreCase(ChatColor.LIGHT_PURPLE + "Titanfall")) {
    104. ArenaManager.getInstance().getArena(Integer.parseInt(s.getLine(1))).addPlayer(e.getPlayer());
    105. }
    106. }
    107. }
    108. }


    Thanks in advance,

    Bram
     
  2. Offline

    _LB

    You should check that it actually is a sign first, and that the block state is an instanceof Sign.
     
  3. Offline

    Gamecube762

    It seems you never checked if it was actually a sign before you started calling it a sign.
     
  4. Offline

    Zettelkasten

    bramhaag Your block is not a sign! Add a check if it is a sign before casting the block state.

    Edit: This forum should really notify you when someone else wrote an answer before you :(
     
  5. Offline

    Gamecube762

    bramhaag Use the location to get the block, then check if the block's state is an instanceof a Sign
     
  6. Offline

    Double0negative

    Code:
    if(block instanceof Sign){
    //now cast to sign
    }
    
     
  7. Gamecube762
    That was what I tried to explain ;) I will try it and post the results in a minute

    Double0negative
    Thanks for the code snippet :D

    Zettelkasten Double0negative _LB

    Still getting the same error, but now on an other line
    Code:java
    1. if(loc.getBlock() instanceof Sign) {//Getting the error on this line
    2. Sign s = (Sign) loc.getBlock().getState();
    3.  
    4. signs.put(s, section.getInt("arenaNumber"));
    5. }


    EDIT: nevermind, it is a NPE

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 9, 2016
  8. Offline

    Zettelkasten

  9. Zettelkasten You're right. So, how to fix it ;). I don't get it... How can a map be null?
     
  10. Offline

    Zettelkasten

    bramhaag Actually, are you sure the map is null? :eek: You do initialize it in line 20!
    Which line does the NPE occur?
     
  11. Zettelkasten Double0negative Gamecube762
    Well, I did some research about the HashMap being null, but that I looked to the error that was generated. So, the hashmap wasn't null.

    The error:
    Code:
    [21:18:47 ERROR]: Error occurred while enabling Titanfall v0.6-ALPHA_BUILD (Is
    t up to date?)
    java.lang.ClassCastException: java.lang.String cannot be cast to org.bukkit.co
    iguration.ConfigurationSection
            at ph.url.techzone.Titanfall.SignManager.<init>(SignManager.java:29) ~
    :?]
            at ph.url.techzone.Titanfall.Main.onEnable(Main.java:47) ~[?:?]
    The code:
    Code:java
    1. for (String str : SettingsManager.getLobbySigns().<ConfigurationSection>get("signs").getKeys(true)) {
    2. ConfigurationSection section = SettingsManager.getLobbySigns().get("signs." + str);// Line 29
    3.  
    4. Location loc = LocationUtil.locationFromConfig(section.getConfigurationSection("location"), false);
    5. if(loc != null && loc.getBlock() instanceof Sign) {
    6. Sign s = (Sign) loc.getBlock().getState();
    7.  
    8. signs.put(s, section.getInt("arenaNumber"));
    9. }


    Nobody? :'(
     
  12. Offline

    Zettelkasten

    bramhaag
    SettingsManager.getLobbySigns().get("signs." + str) returns a ConfigurationSection, not a String. I would need the SettingsManager to find out the exact problem though.
     
  13. The whole class is kinda big, so here you have a snippet :)

    Code:java
    1. public ConfigurationSection createConfigurationSection(String path) {
    2. ConfigurationSection cs = config.createSection(path);
    3. try { config.save(file); }
    4. catch (Exception e) { e.printStackTrace(); }
    5. return cs;
    6. }
     
  14. Offline

    Zettelkasten

    bramhaag The "getLobbySigns()" method is the interesting one :)
     
  15. Here
    Code:java
    1. public static SettingsManager getLobbySigns() {
    2. return lobbySigns;
    3. }


    So, i don't think that you can do a shit with this, here you have the lobbySigns variable :D
    Code:java
    1. private static SettingsManager lobbySigns = new SettingsManager("lobbysigns");


    And now you probaly want the SettingsManager method constructor thingie
    Code:java
    1. private SettingsManager(String fileName) {
    2. System.out.println(Main.getPlugin());
    3.  
    4. if (!Main.getPlugin().getDataFolder().exists()) {
    5. Main.getPlugin().getDataFolder().mkdir();
    6. }
    7.  
    8. file = new File(Main.getPlugin().getDataFolder(), fileName + ".yml");
    9.  
    10.  
    11. if (!file.exists()) {
    12. try {
    13. file.createNewFile();
    14. } catch (Exception e) {
    15. e.printStackTrace();
    16. }
    17. }
    18.  
    19. config = YamlConfiguration.loadConfiguration(file);
    20. }
     
  16. Offline

    Zettelkasten

    bramhaag Can you please post the "lobbysigns.yml" file?
    Also, the method SettingsManager.get(String) would be handy.

    My guess is that the value in lobbysigns.yml for the key "signs" are no Strings but nested configurations.
     
  17. The lobbysigns.yml file
    Code:
    signs:
      '01':
        location:
          world: world
          x: 730.0
          y: 42.0
          z: 312.0
        arenaNumber: 1
    
    And the get method
    Code:java
    1. @SuppressWarnings("unchecked")
    2. public <T> T get(String path) {
    3. return (T) config.get(path);
    4. }
    5.  
    6. //The config variable
    7. config = YamlConfiguration.loadConfiguration(file);// This gets called in the construction thingie
     
  18. Offline

    Zettelkasten

    bramhaag Changing line 28 (i believe) to getKeys(false) should fix your problem.
    What was happening: If you set it to true, it also returns all nested keys, such as signs.01.location.word. And then, of cause, you will only get a boolean ("world"), and no configuration section.

    I will go sleep now, bye bye. Hopefully this solves the problem :)
     
Thread Status:
Not open for further replies.

Share This Page