Por que writeObject lança java.io.NotSerializableException e como faço para corrigir isso?


110

Eu tenho essa exceção e não entendo por que ela seria lançada ou como devo lidar com isso.

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

Onde elementestá um TransformGroupcontendo alguma outra TransformGroupsinstância da 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);
    }
}

O log de erros completo:

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 (na classe Atom) é apenas uma classe personalizada que estende a aparência.


4
Parece que javax.media.j3d.TransformGroupele próprio não implementa Serializable
— micha

Por que Atomambos se estendem Groupe têm um Groupmembro?
— Marquês de Lorne

Respostas:


210

Os campos do seu objeto têm, por sua vez, seus campos, alguns dos quais não implementam Serializable. No seu caso, a classe ofensiva é TransformGroup. Como resolver isso?

  • se a aula é sua, faça Serializable
  • se a classe for de terceiros, mas você não precisar dela no formulário serializado, marque o campo como transient
  • se você precisa de seus dados e de terceiros, considere outros meios de serialização, como JSON, XML, BSON, MessagePack , etc. onde você pode obter objetos de terceiros serializados sem modificar suas definições.

2
Bem, muito obrigado, será uma coisa muito difícil de fazer, uma vez que meus objetos existem apenas como parte do TransformGroup e não há nenhuma variável que os armazene. Meu aplicativo é um construtor de moléculas 3D, e todos os meus átomos e limites são apenas adicionados ao TransformGroup como instâncias - por exemplo, (new Atom ()). O problema não é apenas que eu preciso que eles sejam gravados em um arquivo, mas que o usuário pode querer remover ou editar os objetos atuais. Acho que vou tentar alguma serialização baseada em XML, mas sou um pouco novo no conceito e ainda é um pouco difícil para mim. Obrigado
— Mihai Bujanca

15
Para adicionar a esta excelente resposta: se você precisa de seus dados e é de terceiros, você pode querer agrupar a classe de terceiros em sua própria classe, que implementa Serializablee usa readObject()e writeObject()serializar manualmente os dados da classe de terceiros. Em alguns casos, essa pode ser uma abordagem razoável. stackoverflow.com/a/12963580/1208581
— sulai

76

java.io.NotSerializableExceptionpode ocorrer quando você serializa uma instância de classe interna porque:

serializar tal instância de classe interna resultará na serialização de sua instância de classe externa associada também

A serialização de classes internas (ou seja, classes aninhadas que não são classes-membro estáticas), incluindo classes locais e anônimas, é fortemente desencorajada

Ref: A interface serializável


5
Este foi o meu caso. Estava acontecendo quando peguei um atalho em um teste de unidade. Espero que esta resposta economize algum tempo para outra pessoa.
— user489041

Eu tinha um campo privado final Set <ClaimsNode> outgoing = new TreeSet <ClaimsNode> (new Comparator <ClaimsNode> () {public int compare (ClaimsNode o1, ClaimsNode o2) {return o1.getNativeIndex () - o2.getNativeIndex (); }});
— Vitaly Sazanovich de

1
Incrível, literalmente eu estava nisso há 1 hora. Comecei a duvidar que mesmo os ints primitivos não fossem serializáveis ​​e então me ocorreu que talvez algo esteja realmente errado aqui.
— Shivam Pokhriyal

13

Torne a classe serializável implementando a interface java.io.Serializable.

  • java.io.Serializable - Interface do marcador que não contém métodos.
  • Objetivo da interface do marcador - informar ObjectOutputStreamque esse objeto é um objeto serializável.

7
Você pode ler a pergunta, já está implementando Serializable. Ainda me surpreendem com 12+.
— shaILU de
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.