128 votes

Pourquoi writeObject provoque-t-il une exception java.io.NotSerializableException et comment puis-je y remédier ?

J'ai cette exception et je ne comprends pas pourquoi elle est levée ou comment je dois la traiter.

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

element est un TransformGroup contenant d'autres TransformGroups une instance de la classe 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);
    }
}

Le journal d'erreurs complet :

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 (dans la classe Atom) est juste une classe personnalisée qui étend Appearance.

240voto

Bozho Points 273663

Les champs de votre objet ont à leur tour leurs propres champs, dont certains ne mettent pas en œuvre l'option Serializable . Dans votre cas, la classe incriminée est TransformGroup . Comment le résoudre ?

  • si la classe est la vôtre, faites-la Serializable
  • si la classe est d'un tiers, mais que vous n'en avez pas besoin dans le formulaire sérialisé, marquez le champ en tant que transient
  • si vous avez besoin de ses données et qu'il s'agit d'un tiers, envisagez d'autres moyens de sérialisation, comme JSON, XML, BSON, MessagePack etc. où vous pouvez sérialiser des objets tiers sans modifier leurs définitions.

87voto

ThoQ Luong Points 416

java.io.NotSerializableException peut se produire lorsque vous sérialisez un instance de classe interne parce que :

la sérialisation d'une telle instance de classe interne entraînera la sérialisation de l'instance de classe externe qui lui est associée

Sérialisation des classes internes (c'est-à-dire des classes imbriquées qui ne sont pas classes membres statiques), y compris les classes locales et anonymes, est fortement déconseillé

Réf : L'interface sérialisable

10voto

Prabhakar Points 45

Rendez la classe sérialisable en implémentant l'interface java.io.Serializable .

  • java.io.Serializable - Interface de marqueur qui ne contient aucune méthode.
  • Objectif de l'interface de marquage - indiquer au ObjectOutputStream que cet objet est un objet sérialisable.

1voto

Sid_83 Points 11

Comme mentionné ci-dessus, si la classe est une classe tierce, vous devez la convertir en un objet JSON/XML/BSON car l'objet de la classe tierce ne peut pas être sérialisé.

Je travaillais sur mon projet et j'ai eu le même problème. J'ai utilisé la bibliothèque gson pour convertir mon objet de classe en une chaîne JSON. Ensuite, j'ai utilisé cette chaîne dans cet objet et je l'ai fait passer par l'objet ObjectOutputStream. Et du côté client, j'ai utilisé la même chose pour reconvertir la chaîne JSON en objet de classe tiers.

Vous pouvez télécharger le bocal depuis ici : https://jar-download.com/artifacts/com.google.code.gson/gson/2.8.2/source-code !

Voici comment je l'ai fait :

// 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;
        }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X