Solved Solved

Discussion in 'Plugin Development' started by Pizza371, Jan 16, 2014.

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

    Pizza371

    So.. im trying to load and save objects to a YML file, but, I really can't understand why it's not working.

    So, I have the save method (which I call on onDisable, what I'm trying to save is Mine btw):
    Code:
        public void saveMines() {
            YamlConfiguration yml = new YamlConfiguration();
            for(Mine m : getMines()) {
                System.out.println("saved: " + m.getName());
                yml.set(m.getName(), m);
            }
           
            try {
                yml.save(minedat);
            } catch (IOException e) {
                e.printStackTrace();
            }
           
            plugin.getLogger().log(Level.INFO, getMines().size() + " mine(s) saved.");
        }
    And here is the load method (which I call on onEnable):
    Code:
    public void loadMines() {
            YamlConfiguration yml = YamlConfiguration.loadConfiguration(minedat);
            for(String s : yml.getKeys(false)) {
                System.out.println("YAML KEYS: " + s);
                getMines().add((Mine) yml.get(s));
            }
            plugin.getLogger().log(Level.INFO, getMines().size() + " mine(s) loaded.");
        }
    And I create a mine:
    [​IMG]
    And.. i /reload , and it prints that I saved it (console view):
    [​IMG]
    this is the yaml file containing the mines at this point:
    [​IMG]
    then.. when it loads, it all goes wrong:
    [​IMG]

    No, there isn't any YAML KEYS or anything, the loop doesn't execute in loadMines()
    Maybe I'm doing something stupid.. but I really confused for 2 days, I need help.
    Please notify me if you need more info!

    Help much appreciated!
    Thanks,
    Pizza.

    Bump x_X?

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

    Pizza371

    Bumps? :)
     
  3. Offline

    xTrollxDudex

  4. Offline

    Pizza371

    xTrollxDudex a reply :)
    how will that help? :( I'm using:
    getMines().add((Mine) yml.get(s)); //which gets the Mine object (I hope)

    can you give me an explanation why I need to go deep?
    Shouldn't getKeys(false) be returning just ':confused:'?
    Thanks!
     
  5. Offline

    xTrollxDudex

    Pizza371
    Nevermind, I was thinking of something else
     
  6. Offline

    xTigerRebornx

    Pizza371 In this code here
    Code:
     YamlConfiguration yml = YamlConfiguration.loadConfiguration(minedat)
    I believe that your "minedat" is using an old version of the file (I believe that it is a file). When you call your save method, at the end, make sure to refresh minedat so that you have a fresh version of the file
     
  7. Offline

    Pizza371

    xTigerRebornx Thanks for replying!
    Yes, it is a file.
    I'm not completely sure what you mean?
    At the current state of the plugin whenever I create a mine object in-game with commands they get added to getMines() (which is a HashSet), and it works perfectly..
    then when the server shuts down it saves it all properly because I check the mines.yml file and its all saved (as shown on the pictures in the OP).
    It's just getKeys() doesn't return anything and System.out.println("YAML KEYS: " + s); doesn't do log anything.
    It's just when it comes to loading.. I'm really confused.
    I've scanned the code over and over, and tested it many of times.

    The only time the file is cleared is when I disable the plugin and no Mines were created via commands or loaded on onEnable (which is what is broken, so it's not going to happen).
     
  8. Offline

    xTigerRebornx

    Pizza371 What I mean is that, when you save it, it is saved to the file, but the File minedat (the object itself) is still holding the old version you grabbed when you last set it equal to something. at the end of your save, you could try to redeclare it (something like minedat = new File("locationtofile") or however you get your file.
     
  9. Offline

    Pizza371

    Oh, I only load it on onEnable, so the data is never kept, and I load it on the constructor of the file that holds saveMines, loadMines:
    Code:
    public MineManager(Main m) {
    plugin = m;
    minedat = new File(plugin.getDataFolder(), "dat/mines.yml");
    if(!(minedat.exists())) {
    try {
    minedat.createNewFile();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    xTigerRebornx
     
  10. Offline

    xTigerRebornx

    Pizza371 You'll need to re-"load" it. Could make a load method
     
  11. Offline

    Pizza371

    xTigerRebornx I don't get it? Why would I need to do that?
    I literally create a new instance of the class before I call loadMines(), and thats the only EVER time it gets called.
    anyhow, I added this but it doesn't seem to make a differentse, it still loads nothing, even tho I know the file isn't empty.
    I don't think it makes a difference
    Anyhow, I added this but it doesn't affect it:
    Code:
    public void loadMines() {
    if(minedat == null) {
    minedat = new File(plugin.getDataFolder(), "/dat/mines.yml");
    }
    YamlConfiguration yml = YamlConfiguration.loadConfiguration(minedat);
    for(String s : yml.getKeys(false)) {
    System.out.println("YAML KEYS: " + s);
    getMines().add((Mine) yml.get(s));
    }
    plugin.getLogger().log(Level.INFO, getMines().size() + " mine(s) loaded.");
    }
    Thank you!
     
  12. Offline

    xTigerRebornx

    Pizza371
    Code:
    if(minedat == null) {
    minedat = new File(plugin.getDataFolder(), "/dat/mines.yml");
    }
    Well, its already loaded, so the minedat = blabla is never ran. You need to do that part regardless of it being null or not, otherwise you'll still be using the blank file from when its called the first time (I believe).
     
  13. Offline

    Pizza371

    xTigerRebornx I'm so confused o_o
    what's wrong with using the file from the constructor?
     
  14. Offline

    xTigerRebornx

    Pizza371 Taken from the Oracle Javadocs for Java 7
    Code:
    public File(String pathname)
    Creates a new File instance by converting the given pathname string into an abstract pathname. If the given string is the empty string, then the result is the empty abstract pathname.
    I am thinking that the instance you are using from the constructor is the one that is the blank file, therefor its loading it blank.
     
  15. Offline

    Pizza371

    xTigerRebornx Ohhh! I get you, lol.
    It would make sense.. but I believe I'm getting the path right
    [​IMG]
    *clicks on dat*
    [​IMG]
    minedat = new File(plugin.getDataFolder(), "/dat/mines.yml");
    ?
     
  16. Offline

    xTigerRebornx

    Pizza371 I'd use File.seperator instead of a /, as it might cause problems with other OS. Either way, running that code would work fine if you've saved the file properly.
     
  17. Offline

    Pizza371

    xTigerRebornx yeah, thanks for the tip.
    I know the path is the same as what it is being saved to as I use the same Object.
    This is why I'm so confused!
    Thanks for the help anyway :)
     
  18. Offline

    xTigerRebornx

    Pizza371 You are using the same File Object, but if you never update the instance in it, it will always have the same instance of the file it grabbed, which in your case is the blank one.
     
  19. Offline

    Pizza371

    xTigerRebornx
    saveMines() or any other alterations to the File object get changed before calling loadMines() in my code

    Can anyone else see anything abnormal?

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

    Pizza371

    Bump post

    Bump
    Anyone? I'm really confus.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 6, 2016
  21. xTigerRebornx a File instance NEVER needs reloading since it only represents the path or file string, not the content. The underlying file doesn't even have to exist and thus "reloading" is senseless.
    From the oracle doc:

    Pizza371 Have you tried putting them under a root node? On load, .get(<rootnode>) should then return a map<String, Mine>.

    And just to be sure, that they can be deserialized properly, did you provide a constructor which only accepts a map<String, object> parameter?
     
  22. Offline

    Pizza371

    kumpelblase2
    Whoops, changed code around a bit as I thought I was going to have to work it out for myself or load/save a different way.
    I changed it for the better (IMO) so it has multiple files, yet it still won't load!
    And yes, I have that constructor:
    Code:
    public Mine(HashMap<String, Object> map) {
            this.x = (int) map.get("x");
            this.y = (int) map.get("y");
            this.z = (int) map.get("z");
            this.maxX = (int) map.get("maxX");
            this.maxY = (int) map.get("maxY");
            this.maxZ = (int) map.get("maxZ");
            this.name = (String) map.get("name");
            this.w = Bukkit.getWorld((String) map.get("world"));
        }
    My updated save/load methods:
    Code:
    public void saveMines() {
    for(Mine m : getMines()) {
    File f = new File(plugin.getDataFolder(), "dat" + File.separator + "mines" + File.separator + m.getName() + ".yml");
    if(!(f.exists())) {
    try {
    f.createNewFile();
    } catch (IOException e) {
    plugin.getLogger().log(Level.SEVERE, "An exception occured while attempting to create file: " + m.getName() + ".yml; Mine: " + m.getName() + " can't be saved.");
    e.printStackTrace();
    continue;
    }
    }
    YamlConfiguration yc = YamlConfiguration.loadConfiguration(f);
    yc.set("data", m);
    try {
    yc.save(f);
    } catch (IOException e) {
    plugin.getLogger().log(Level.SEVERE, "An exception occured while attempting to save information to file: " + m.getName() + ".yml.");
    e.printStackTrace();
    }
    }
    plugin.getLogger().log(Level.INFO, getMines().size() + " mine(s) saved.");
    }
     
    public void loadMines() {
    for(File f : minedat.listFiles()) {
    YamlConfiguration yc = YamlConfiguration.loadConfiguration(f);
    Object ob = yc.get("data");
    if(!(ob instanceof Mine)) {
    plugin.getLogger().log(Level.INFO, "Failed to deserialize and load Mine: " + f.getName().replace(".yml", "") + "!");
    } else {
    Mine m = (Mine) ob;
    getMines().add(m);
    }
    }
     
    plugin.getLogger().log(Level.INFO, getMines().size() + " mine(s) loaded.");
    }
    Example Mine:
    [​IMG]

    When trying to load this Mine from this file:
    [​IMG]
    .. what other information?

    btw with every mine it attempts to load it prints this line:
    plugin.getLogger().log(Level.INFO, "Failed to deserialize and load Mine: " + f.getName().replace(".yml", "") + "!");

    I don't understand why it's not a mine object?
    Much appreciated if any help,
    thanks!
     
  23. Pizza371 likes this.
  24. Offline

    xTigerRebornx

    Pizza371
    Code:
    Object ob = yc.get("data");
    if(!(ob instanceof Mine))
    Instead of this, could you try and use a try/catch statement and do the casting of ob to mine in the try, then catch exceptions there?
     
  25. Offline

    Pizza371

    kumpelblase2 Thanks for that! I changed it to Map<String, Object> and at least it's giving errors.
    I have this on my onEnable:
    ConfigurationSerialization.registerClass(Mine.class);

    I have no idea what the error means.. what is 'Name'?
    [​IMG]

    and it links me to these two pieces of code
    [​IMG]

    MineManager line 58 (loadMines method):
    YamlConfiguration yc = YamlConfiguration.loadConfiguration(f);
    Main line 42 (onEnable override):
    getMM().loadMines(); // getMM() = instance of MineManager

    EDIT: put my computet to sleep while in the middle of posting :p
    xTigerRebornx Thanks, but I have a stacktrace to work with now, but unfortunately i have no idea what it means, lol.
     
  26. Offline

    xTigerRebornx

    Pizza371 Well, the Mine object has a constructor, and my guess is that you aren't using a constructor for it (Hence the "IllegalArgumentException" and the Name cannot be null).
    Can we see the Mine object, and any other classes that are involved in the stacktrace, along with the text form of the stacktrace?
     
  27. xTigerRebornx You know that the yml constructs it for him right?

    Pizza371 Can you just try and set your name variable inside the mine to something static? Like just this.mine = "test" and load it?
     
    Pizza371 likes this.
  28. Offline

    xTigerRebornx

    kumpelblase2 Don't use serialization much, so I don't know :p
    Ill have to look into it sometime
     
  29. Offline

    Pizza371

    kumpelblase2 xTigerRebornx thank yous soo much!! :)
    I tried to replace the name with "test" that didn't work, so I randomly decided to check if instead of using getWorld(String) I used getWorlds().get(0); and it worked perfectly.. So I checked whether I was saving..
    ..and you can guess the rest (facedesk).
    Although my initial error was assuming it was HashMap. :)
    Anyhow, much appreciated!
     
  30. Pizza371 Oh damn, should've seen that. At least you figured it out yourself ;)
     
Thread Status:
Not open for further replies.

Share This Page