Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm trying to load an object into Java that I had saved from a program I had made.

When loading it in, Java threw a Stack Overflow Error.

The object I'm loading in had about a thousand entry object ArrayList inside of it, and in total ended up being around 128 Kb when exported.

I understand that a Stack Overflow happens when I make too many recursive calls, but I don't understand how loading in one array list of objects can cause this to happen?

I'm a self-taught programmer, so any insight would be appreciated that could help me better understand the problem.

Here's my code for the class I'm trying to load (Memboric)

    public class Memboric implements Serializable{

    /**
     *
     * The Memboric Core stores the various databases the AI needs to function.
     *
     * @author Brayden McKinney
     * @date 5/14/2013
     */

    private static final long serialVersionUID = 4477889114653605232L;

    ArrayList<String> knownWords = new ArrayList<String>();
    HashMap<String, Word> thesaurus = new HashMap<String, Word>();
    ArrayList<ConversationLog> conversations = new ArrayList<ConversationLog>();

    File location = null;

    public static Memboric load(File location){
            Memboric memboric;

            try{
                    FileInputStream file = new FileInputStream(location);
                    ObjectInputStream oo = new ObjectInputStream(file);
                    memboric = (Memboric) oo.readObject();
                    oo.close();
                    System.out.println("Memboric Core loaded and mounted successfully.");
                    return memboric;
            }catch(FileNotFoundException fn){
                    System.err.println("Failed to load Memboric Core.");
            }catch(InvalidClassException ic){
                    System.err.println("Memboric Core is incompatible.");
            }catch(Exception e){
                    e.printStackTrace();
            }

            System.err.println("Creating new Memboric Core.");
            return new Memboric();
    }

    public boolean save(File location){
            this.location = location;

            try{
                    FileOutputStream file = new FileOutputStream(location);
                    ObjectOutputStream oo = new ObjectOutputStream(file);
                    oo.writeObject(this);
                    oo.close();
                    System.out.println("Memboric Core saved successfully.");
                    return true;
            }catch(FileNotFoundException ex){
                    try{
                            if (location.createNewFile()) save(location);
                    }catch(IOException exx){
                            exx.printStackTrace();
                    }
            }catch(Exception e){
                    e.printStackTrace();
            }

            return false;
    }

And it's sister class (Word) that it contains:

    public class Word implements Serializable{

    private static final long serialVersionUID = 790247641945230263L;

    private String word;

    ArrayList<String> definitions = new ArrayList<String>();
    ArrayList<Word> synonyms = new ArrayList<Word>();
    ArrayList<String> tags = new ArrayList<String>();
    HashSet<String> links = new HashSet<String>();
    }

The error itself can be seen here (it's rather large): http://pastebin.com/46bFZYVp

Also, the code above is cut down to save space (I removed the non-related parts) but the full classes can be seen here:

http://pastebin.com/tptmZ2LC http://pastebin.com/3ickseFL

share|improve this question
4  
You could start by editing your post to include the stack trace (complete) and telling us which line in your code threw the exception. –  Jim Garrison May 20 '13 at 7:14
    
One moment, I'll edit the post. –  Brayden May 20 '13 at 7:20
1  
So what's inside that array? Don't you have circular references somewhere? –  dratewka May 20 '13 at 7:25
    
Oh, I see the problem now. The object contains a list of words, and each word contains a reference to another word that it's a synonym with. I'll have to find a way to bypass this. –  Brayden May 20 '13 at 7:31
    
That shouldn't cause an issue - the ObjectInputStream caches new instances and then, for each new object, checks the cache. This means that circular references should be resolved from the cache and not result in a infinite loop. –  Boris the Spider May 20 '13 at 7:32

1 Answer 1

Move synonyms outside of Word and track it in Memboric or some other class:

class Memboric {

    private Map<String, Word> dictionary;
    private Map<Word, Set<Word>> thesaurus;

}

Basically, from a design standpoint, a Word can know about its own attributes but should not know how it relates to other words; each word is independent. Some higher-level object can know about relationships between words. This prevents cycles between object references.

Edit: The above works assuming Word implements hashCode() and equals() correctly; if not or it's too much trouble, then use Map<String, Set<String>> for the thesaurus.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.