135

I have this exception and I don't understand why it would be thrown or, how I should handle it.

try {
    os.writeObject(element);
} catch (IOException e) {
    e.printStackTrace();
}

Where element is a TransformGroup containing some other TransformGroups an instance of the class Atom:

public class Atom extends Group implements Serializable{
    float pozX,pozY;
    Group group= new Group();   
    Color3f blue = new Color3f(new Color(255));
    Color3f black = new Color3f(new Color(0));
    Sphere AtSph=new Sphere();

    public Atom(final float WEIGHT, final int BOUNDS,final float radius,Color3f color)
    {
        AppSetting ap= new AppSetting(color, black);
        AtSph=new Sphere(radius,1,100,ap);
    }
}

The full error log:

java.io.NotSerializableException: javax.media.j3d.TransformGroup
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at cls.MolecularBuilder.addAtom(MolecularBuilder.java:511)
    at cls.MolecularBuilder$Console.HidrogenItemActionPerformed(MolecularBuilder.java:897)
    at cls.MolecularBuilder$Console$2.actionPerformed(MolecularBuilder.java:746)
    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$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$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)

AppSetting (in Atom class) is just a custom class that extends Appearance.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
Mihai Bujanca
  • 4,089
  • 10
  • 43
  • 84

4 Answers4

250

The fields of your object have in turn their fields, some of which do not implement Serializable. In your case the offending class is TransformGroup. How to solve it?

  • if the class is yours, make it Serializable
  • if the class is 3rd party, but you don't need it in the serialized form, mark the field as transient
  • if you need its data and it's third party, consider other means of serialization, like JSON, XML, BSON, MessagePack, etc. where you can get 3rd party objects serialized without modifying their definitions.
Community
  • 1
  • 1
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 2
    Well, thanks a lot, it will be quite a hard thing to do, since my objects only exist as part of the TransformGroup, and there are not any variables that store them. My app is a 3d molecule builder, and all my atoms and bounds are just added to the TransformGroup as instances- e.g (new Atom()). The problem is not only that I need them written to a file, but that the user may want to remove or edit current objects. I think I will try some XML-based serialization, but I am quite new to the concept and it's a bit hard for me yet. Thank you – Mihai Bujanca Dec 15 '12 at 20:35
  • 19
    To add to this excellent answer: if you need its data and it's third party, you may want to wrap the third party class into your own class, which implements `Serializable` and uses `readObject()` and `writeObject()` to manually serialize the data of the third party class. In some cases this might be a reasonable approach. http://stackoverflow.com/a/12963580/1208581 – sulai Mar 09 '14 at 18:10
89

java.io.NotSerializableException can occur when you serialize an inner class instance because:

serializing such an inner class instance will result in serialization of its associated outer class instance as well

Serialization of inner classes (i.e., nested classes that are not static member classes), including local and anonymous classes, is strongly discouraged

Ref: The Serializable Interface

Community
  • 1
  • 1
Tho
  • 23,158
  • 6
  • 60
  • 47
  • 8
    This was the case for me. It was happening when I took a short cut on a unit test. Hope this answer saves someone else some time. – user489041 Jun 12 '19 at 14:35
  • 1
    I had a field private final Set outgoing = new TreeSet(new Comparator() { public int compare(ClaimsNode o1, ClaimsNode o2) { return o1.getNativeIndex() - o2.getNativeIndex(); } }); – Vitaly Sazanovich Aug 26 '19 at 15:36
  • 1
    Amazing, Literally I was into this for past 1 hour. I started doubting that even primitive ints are not serializable and then it occurred to me, that perhaps something is really wrong here. – Shivam Pokhriyal Jun 15 '20 at 09:49
10

Make the class serializable by implementing the interface java.io.Serializable.

  • java.io.Serializable - Marker Interface which does not have any methods in it.
  • Purpose of Marker Interface - to tell the ObjectOutputStream that this object is a serializable object.
user207421
  • 305,947
  • 44
  • 307
  • 483
Prabhakar
  • 311
  • 3
  • 7
2

As mentioned above if the class is a 3rd party class you need to convert it to a JSON/XML/BSON object as the 3rd party class object cannot be serialized.

I was working on my project and had the same issue and i used gson library to convert my class object to a JSON String. Afterwhich i used this String in that object and passed it through ObjectOutputStream object. And over the client side i used the same to revert the JSON String back to the 3rd party class object.

You can download the jar from over here : https://jar-download.com/artifacts/com.google.code.gson/gson/2.8.2/source-code!

Here's how i did it :

// Method that returns String through a Object as a parameter i.e to be converted

 public static String  generateJSONStringFromObject(ThirdPartyClass object) throws JsonProcessingException{
            ObjectMapper mapper = new ObjectMapper();
            mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
            String jsonString = mapper.writeValueAsString(object);
            
                return jsonString;
        }

// Method that returns Object through a String as a parameter 

 public static ThirdPartyClass generateObjectFromJSONString(String jsonString){
            Gson gson = new Gson();
            ThirdPartyClass thirdPartyClassObject = gson.fromJson(jsonString, ThirdPartyClass.class);
            return thirdPartyClassObject;
        }

Sid_83
  • 21
  • 2