lordraiden15
lordraiden15

Reputation: 41

Getting NotSerializableException on a serializable object

Basically, I've written a program that paints shapes onto the screen, and saves each of the shapes into an ArrayList. What I want to do is figure out how to save the ArrayList to a file, so that I can call it back up later and edit the already existing shapes.

So I've been having some trouble figuring out why exactly I keep getting a NotSerializableException when I made the object Shape serializable already.

Below is the save portion of my code, and the Shape object.

save.addActionListener(new ActionListener(){
  public void actionPerformed(ActionEvent e){
    int returnVal = fc.showSaveDialog(BallWorld.this);
    if(returnVal == JFileChooser.APPROVE_OPTION){
      File file = fc.getSelectedFile();
      ArrayList list = bp.shapes;
      FileOutputStream fos = null;
      ObjectOutputStream oos = null;
      try{
        fos = new FileOutputStream(file);
        oos = new ObjectOutputStream(fos);
        oos.writeObject(list);
        oos.close();
      }
      catch(IOException ex){
        ex.printStackTrace();
      }
    }
  }
});

  public class Shape implements Serializable{
    int radius;
    Point center;
    Color color;
    int sides;
    Polygon shape;
    public Shape(int _radius, Point _center, Color _color, int _sides){
      radius = _radius;
      center = _center;
      color = _color;
      sides = _sides;
    }
    public void draw(Graphics g){
      Graphics2D g2d = (Graphics2D) g; 
      g2d.setColor(color);
      shape = new Polygon();
      if(sides != 0 && sides != 4){
        if(sides % 2 == 0){
          if(sides / 2 % 2 == 0){
            for(int i = 0; i < sides; i++){
              shape.addPoint((int) (center.x + radius * Math.cos(i * 2 * Math.PI / sides - Math.PI / sides)), (int) (center.y + radius * Math.sin(i * 2 * Math.PI / sides - Math.PI / sides)));
            }
          }
          else if(sides / 2 % 1 == 0){
            for(int i = 0; i < sides; i++){
              shape.addPoint((int) (center.x + radius * Math.cos(i * 2 * Math.PI / sides)), (int) (center.y + radius * Math.sin(i * 2 * Math.PI / sides)));
            }
          }
        }
        else{
          for(int i = 0; i < sides; i++){
            shape.addPoint((int) (center.x + radius * Math.cos(i * 2 * Math.PI / sides - Math.PI / 2)), (int) (center.y + radius * Math.sin(i * 2 * Math.PI / sides - Math.PI / 2))); 
          }
        }
        g2d.fillPolygon(shape);
      }
      else if(sides == 4){
        g2d.fillRect(center.x - radius, center.y - radius, radius * 2, radius * 2);
      }
      else{
        g2d.fillOval(center.x - radius, center.y - radius, radius * 2, radius * 2);
      }
      repaint();
    }
    public boolean contains(Point p){
      if(sides == 0){
        if(center.distance(p) <= radius){
          return true;
        }
      }
      else if(sides == 4){
        if(p.x <= center.x + radius && p.x >= center.x - radius && p.y <= center.y + radius && p.y >= center.y - radius){
          return true;
        }
      }
      else{
        if(shape.contains(p)){
          return true;
        }
      }
      return false;
    }
  }

java.io.NotSerializableException: javax.swing.plaf.basic.BasicFileChooserUI$AcceptAllFileFilter
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeArray(Unknown Source)
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.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteObject(Unknown Source)
at javax.swing.JComboBox.writeObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(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.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteObject(Unknown Source)
at javax.swing.JLabel.writeObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(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.writeArray(Unknown Source)
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.writeObject(Unknown Source)
at javax.swing.ArrayTable.writeArrayTable(Unknown Source)
at javax.swing.JComponent.writeObject(Unknown Source)
at sun.reflect.GeneratedMethodAccessor11.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(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.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.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteObject(Unknown Source)
at java.awt.Window.writeObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(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.writeObject(Unknown Source)
at java.awt.Window.writeObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(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.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.writeObject(Unknown Source)
at java.util.ArrayList.writeObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(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.writeObject(Unknown Source)
at BallWorld$2.actionPerformed(BallWorld.java:112)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Upvotes: 3

Views: 2336

Answers (2)

Victor Basso
Victor Basso

Reputation: 5796

To avoid NotSerializableException make sure:

  1. your class implements Serializable
  2. all non primitive members implement Serializable (or are transient instead)
  3. if your class is an inner class it's either static or the outer class implements Serializable

Besides that you also need to define serialVersionUID for every Serializable class. Check all 3 cases above plus:

  1. all Serializable superclasses
  2. if your class is an anonymous class, define it there too

Note: your code may work without serialVersionUID sometimes but read the last paragraph in Serializable's javadoc to understand why it will be a problem depending on the environment.


There's a VM option to add details to the exception. It shows the root and nested classes failing to serialize:

-Dsun.io.serialization.extendedDebugInfo=true

Upvotes: 4

Russell Zahniser
Russell Zahniser

Reputation: 16364

Based on the call you are making to repaint() in Shape, I'm guessing that it is in inner class. It therefore has a hidden variable referencing its enclosing instance. It will try to serialize that object along with itself. Is the outer class serializable? Or better yet, could Shape be made into an ordinary top-level class?

Upvotes: 3

Related Questions