Problem with serialization

Hi,

I have a problem with serialization. Some users of my game experience crashes when attempting to serialize or deserialize the world. One user reported a stackoverflowerror while another user reported a massive fps frop after saving followed by a crash 2 seconds later.
I can’t replicate this crash because it seems to work perfectly fine for most users including myself.

here is the code:



    public static void saveWorld(R_Object[] groundtile_list, String foldername, String filename, String extension)
    {
        boolean savedsucces = false;
        String temp_pathname = foldername+"\\"+filename+"_temp"+extension;

        try (FileOutputStream fos = new FileOutputStream(temp_pathname)) {
            //File outputsteam saves to file
            //objectoutputstream does serialization
            try (ObjectOutputStream out = new ObjectOutputStream(fos)) {
                out.writeObject(groundtile_list);    
                savedsucces = true;
            }
            catch(IOException e) {
                System.out.println(e.toString());
                JOptionPane.showMessageDialog(null, "objectoutputstream error: "+e.toString());
            } 
            catch(Exception e) {
                System.out.println(e.toString());
                JOptionPane.showMessageDialog(null, "objectoutputstream error: "+e.toString());
            }   
        }
        catch(IOException e) {
            System.out.println(e.toString());
            JOptionPane.showMessageDialog(null, "fileoutputstream error: "+e.toString());
        } 
        catch(Exception e) {
            System.out.println(e.toString());
            JOptionPane.showMessageDialog(null, "fileoutputstream error: "+e.toString());
        }     
        
        if (savedsucces == true) {
            try {
                File folder = DopplerMath.getFolder(foldername+"\\");
                File filetemp = DopplerMath.getFile(folder, filename+"_temp", extension);

                //delete old save if it exist
                File fileold = DopplerMath.getFile(folder, filename, extension);
                if (fileold != null) {
                    fileold.delete();
                }

                filetemp.renameTo(new File(foldername+"\\"+filename+extension));    
            }
            catch(Exception e) {
                JOptionPane.showMessageDialog(null, "failed to save world: "+e.toString());
            }
        }  
    }  

    public static R_Object[] loadWorld(String filename)
    {
        R_Object[] groundtilelist = null;
        
        try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename))) {
            groundtilelist = (R_Object[]) in.readObject();   
            return(groundtilelist);
        }
        catch(IOException | ClassNotFoundException e) {
            JOptionPane.showMessageDialog(null, "failed to load world: "+e.toString());
        } 
        catch(Exception e) {
            JOptionPane.showMessageDialog(null, "failed to load world: "+e.toString());
        } 
        return(groundtilelist);  
    }

Am I doing something wrong here?
I have been googling for an answer but could not find any.
My guess would be that the person experiencing the stackoverflow somehow starts the application with a lower maximum stack size.

Code looks fine from what I can tell.

Can they reproduce the errors? If not then I’m not really sure what we can do.

Was the stackoverflow on load or save? Not sure how you’re handling getting the file from disk, you may take a look here:

Stock overflow was on save, but crashes where reported on both loading and saving.
Could it be that for some players the right folders could not be found?
The files I am trying to acces are not inside the jar btw, but in a folder at the same location as the jar.
This is the code I use for getting files and folder:


    public static File getFile(File folder, String filename, String extension)
    {
        if (folder.exists()) {
            File[] listOfFiles = folder.listFiles();

            for (File file : listOfFiles)  {
                if (file.isFile())  {
                    if (file.getName().endsWith(extension)) {
                        if (file.getName().equals(filename+extension)) {
                            return(file);
                        }
                    }
                }
            }
        }
        return(null);
    }

    //tries to find a folder, creates a new one if it doesnt exist
    public static File getFolder(String foldername)
    {
        File dir = new File(foldername);

        //check if save folder already exists
        if (!dir.exists()) {
            //create new directory for saving files
            dir = new File(foldername);
            dir.mkdir();
        }
        return(dir);
    }

You don’t close both DataInputStream/DataOutputStream.
It can be the cause of your problems, I think.

I am using a try with resources, which means it is closed automatically if I am not mistaken.

No way to tell without the actual error stacktraces. Ask your users to start the game on the console and post the full output. Also are you packaging your own copy of the JRE? If not, it’s highly recommended to not have to debug for a myriad of JRE versions. Also start the game from a wrapper to set required heap and stack sizes yourself.

You should put the .close() in there anyway, explicit enforced design is always better (except in the cases where it isn’t…), but it shouldn’t cause the crashes unless something weird is happening.

[quote]Also start the game from a wrapper to set required heap and stack sizes yourself.
[/quote]
^ This is a must.

I have not used a wrapper, thanks for the advice.

This is what I was going to recommend, but cylab got there first.

Thanks. I am going to try to make a wrapper with je JVM included.
I am following this manual: http://www.java-gaming.org/topics/professional-looking-games-bundling-jres-and-making-native-executables/35990/view.html