4 Replies Latest reply: Dec 21, 2009 5:25 PM by 843790 RSS

    NotSerializable error while trying to write arraylist

    843790
      I am getting a NotSerializable error while trying to write an arraylist to a file.

      Here's the part of the code causing problem
      File temp = fileOpenerAndSaver.getSelectedFile(); // fileOpenerAndSaver is a JFileChooser object which has been created and initialized and was already used to select a file with
      currentWorkingFile = new File (temp.getAbsolutePath() + ".gd");      // currentWorking file is a file object
      
      try 
      {
           ObjectOutput output = new ObjectOutputStream (new BufferedOutputStream(new FileOutputStream(currentWorkingFile)));
           output.writeObject(nodeList); // <-- This is the line causing problem (it is line 1475 on which exception is thrown)
           output.writeObject(edgeList);
           output.writeObject(nodesWithSelfLoop);
           output.writeObject(nextId);
           output.writeUTF(currentMessage);
           output.close();
      } 
      catch (Exception e2)
      {
           JOptionPane.showMessageDialog (graphDrawer, "Unknown error writing.", "Error", JOptionPane.ERROR_MESSAGE);
           e2.printStackTrace();
      }
      As far as what nodeList is -- it's an arraylist of my own class Node which has been serialized and any object used inside the class has been serialized as well.
      Here is the declaration of nodeList:

           
      private ArrayList <Node> nodeList; // ArrayList to hold a list all the nodes
      Let me show you whats inside the node class:
      private class Node implements Serializable
      {
           /**
            * 
            */
           private static final long serialVersionUID = -4625153386839971250L;
           /*  edgeForThisNodeList holds all the edges that are between this node and another node
            *  nodesConnected holds all the nodes that are connected (adjacent) to this node
            *  p holds the top left corner coordinate of this node.  The centre. of this node is at (p.x + 5, p.y + 5)
            *  hasSelfLoop holds whether this node has a self loop. 
            *  **NOTE**: ONLY ONE SELF LOOP IS ALLOWED FOR A NODE.
            */
           ArrayList <Edge> edgeForThisNodeList = new ArrayList <Edge> ();
           ArrayList <Node> nodesConnected = new ArrayList <Node> ();
           Point p;
           boolean hasSelfLoop = false;
           int index = -1;
           BigInteger id;
      
                       ... some methods following this....
      }
      Here is the edge class
      private class Edge implements Serializable
      {
           /**
            * 
            */
           private static final long serialVersionUID = -72868914829743947L;
           Node p1, p2; // The two nodes
           Line2D line;
      
           /*
            * Constructor: 
            * Assigns nodes provided as appropriate.
            * Also calls the addEdge method on each of the two nodes, and passes
            * "this" edge and the other node to the nodes, so that
            * this edge and the other node can be added to the
            * data of the node.
            */
           public Edge (Node p1, Node p2)
           {
                this.p1 = p1;
                this.p2 = p2;
                line = new Line2D.Float(p1.p.x+5,p1.p.y+5,p2.p.x+5,p2.p.y+5);
                p1.addEdge(this, p2, true);
                p2.addEdge(this, p1, false);
           }          
           }
      Here is the error I am getting:
      java.io.NotSerializableException: javax.swing.plaf.metal.MetalFileChooserUI
           at java.io.ObjectOutputStream.writeObject0(Unknown Source)
           at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
           at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
           at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
           at java.io.ObjectOutputStream.writeObject0(Unknown Source)
                      ...
           at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
           at java.io.ObjectOutputStream.writeObject0(Unknown Source)
           at java.io.ObjectOutputStream.writeObject(Unknown Source)
           at MyPanel.save(MyPanel.java:1475)
           at GraphDrawer.actionPerformed(GraphDrawer.java:243)
      
                       ...
           
      I inentionally did not write the whole error stack because it was way too long and I ran out of characters. But line 1475 is where I do the writeObject call. I also goet some weird not serialized exceptions before on some other classes that are not being written to the file or are not part of the object that I am writing. I serialized those classes and now it's this unknown object that's causing problems.

      Edit: The problem may be due to the JFileChooser I am using to select the file as it is a non-serializable object. But I am not trying to write it to the file and in fact am just writing the arrayLists and BigInteger as objects to the file.

      Edited by: Cricket_struck on Dec 21, 2009 1:25 PM

      Edited by: Cricket_struck on Dec 21, 2009 1:32 PM

      Edited by: Cricket_struck on Dec 21, 2009 2:16 PM
        • 1. Re: NotSerializable error while trying to write arraylist
          EJP
          java.io.NotSerializableException: javax.swing.plaf.metal.MetalFileChooserUI
          That's a Swing component and it is clearly related to the JFileChooser.
          I also get some weird not serialized exceptions before on some other classes that are not being written to the file or are not part of the object that I am writing.
          That's a contradiction in terms. If you get NotSerialzableException it means the objects are being written. So they are reachable from the objects you're writing.
          Edit: The problem may be due to the JFileChooser I am using to select the file as it is a non-serializable object.
          JFileChooser implements Serializable, but you're right, you shouldn't try to serialize it. But clearly this is the current problem. Somewhere you have a reference to it reachable via the object(s) you are serializing.

          I suspect that Node and Edge inner classes and that you aren't aware that inner classes contain a hidden reference to their containing class. The solution for serializaition purposes is to make them static nested classes, or outer classes.
          • 2. Re: NotSerializable error while trying to write arraylist
            843790
            Hi,
            Thanks for the reply.

            The problem is that the Node class accesses the nodeList object of the outer class and thus I cannot make it a separate class. The outer class contains an object, which in return contains an object, and that object contains a reference to a JFileChooser.

            i.e. Node class needs a reference to MyPanel class (the outer class) to modify an arraylist in one of its methods. MyPanel class has a reference to class GraphDrawer. GraphDrawer has a reference to GetFile class. GetFile class has a JFileChooser object.


            If I make Node a separate class, I would have to make a reference to the MyPanel in the Node class to be able to call a method in MyPanel class to do the modification that was done previously in a method in the Node class. Would having a static reference to the MyPanel class in the Node class solve the problem?

            Edited by: Cricket_struck on Dec 21, 2009 2:54 PM

            Edited by: Cricket_struck on Dec 21, 2009 3:06 PM
            • 3. Re: NotSerializable error while trying to write arraylist
              EJP
              The problem is that the Node class accesses the nodeList object of the outer class and thus I cannot make it a separate class.
              Pass it as a parameter to the constructor and have a local copy in Node.
              • 4. Re: NotSerializable error while trying to write arraylist
                843790
                Hi,
                Thanks for the help. The problem is solved now.