0

I have this code and it throws the exception

java.io.NotSerializableException: javax.swing.GroupLayout

The code is the following

package basededatosmuebleria;
import FrontEnd.VentanaIngresoMedianteArchivo;
import java.io.*;
import javax.swing.JOptionPane;

public class FileController implements Serializable {
    public static void escribirObjetoPieza(String nombre, Pieza pieza){
        try{
            ObjectOutputStream fileOut = new ObjectOutputStream(
        new FileOutputStream(nombre));
        fileOut.writeObject(pieza);
        fileOut.close();
        }
        catch (IOException e){ 
            JOptionPane.showMessageDialog(null, e);
        }
    }
}

The class that sends invokes the method is the following ...

package basededatosmuebleria;
import FrontEnd.VentanaIngresoMedianteArchivo;
import static java.lang.Double.parseDouble;
import java.util.StringTokenizer;
import java.io.*;

public class Pieza implements Serializable {
    String tipo;
    double costo;
    VentanaIngresoMedianteArchivo comunicador = new                     
    VentanaIngresoMedianteArchivo();
    public Pieza(String tipo, double costo){
        this.tipo=tipo;
        this.costo=costo;
    }
    public Pieza(){}
    public String getTipo(){
        return this.tipo;
    }
    public double getCostoPieza(){
        return this.costo;
    }
    public void evaluarLinea(String line) {
            try{
            StringTokenizer token = new StringTokenizer(line,",");
            tipo=token.nextToken()
                    .replaceAll("PIEZA", "")
                    .replace("(", "")
                    .replaceAll("\"","");
            costo=parseDouble(token.nextToken()
                    .replace(")",""));
            Pieza pieza = new Pieza (tipo, costo);
            int contador = FileController.leerContadorPiezas(tipo);
            String nombreDelObjeto=
                    "Pieza"
                    +tipo
                    +String.valueOf(contador)
                    +".dat";
            FileController.escribirObjetoPieza(nombreDelObjeto, pieza);   
        }
        catch(NullPointerException e){
            VentanaIngresoMedianteArchivo.cajaDeMensajes.append("No se ha ingresado un valor en el precio de la pieza");
        }
        catch(NumberFormatException e){
            VentanaIngresoMedianteArchivo.cajaDeMensajes.append("El formato ingresado es incorrecto. no es un numero real");
        }
    }  
}
Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
  • 2
    You may be serialising the instance of `VentanaIngresoMedianteArchivo`, which may be causing the issue. Since you're not actually using it, I'd remove the property. Personally, I'd avoid seralisation, as you have little control over it, and might consider using something like [jaxb](https://docs.oracle.com/javase/tutorial/jaxb/intro/). If you don't like XML, there's probably even some JSON library which can do the same thing – MadProgrammer May 21 '18 at 01:49
  • 1
    Why would you ever want to serialize a program's view to begin with? You will want to instead serialize the program's *model*, and then use it to reconstruct the view where needed. – DontKnowMuchBut Getting Better May 21 '18 at 02:08
  • @stdunbar Not really. The only solution suggested there is infeasible for an existing JDK class. – user207421 May 21 '18 at 04:23
  • Reopened. None of duplicates answered the question with a usable recommendation. The only solution here is a redesign that doesn't rely on serializing the layout. – user207421 May 23 '18 at 23:40

2 Answers2

1

As the exception message states, javax.swing.GroupLayout is not serialisable.

What to do?

Your favourite Java Serialisation reference should give you the options in this case. Briefly your choices are:

  • Use a serialisable LayoutManager. (I never liked GroupLayout.)
  • Subclass GroupLayout with a class that implements Serializable. The subclass should copy out all of the state from the superclass in a custom writeObject and copy in back in in a custom readObject (a variation is to use a serial proxy with writeReplace and readResolve, but that's even more complication).
  • "Manually" remove the layout before serialisation and either manually replace on deserialisation or insert a serial proxy (a LayoutManager with a readResolve method).
  • Use an alternative serialisation mechanism. Java Serialisation has now been seriously, publicly proposed for removal. However, alternative serialisation mechanisms are likely to be much worse.
  • Write a "hand-rolled" specific serialiser to JSON or similar.
  • Don't serialise UIs. This is the best choice.
Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
1

If you happen to be using Javax.swing and you have been using PropertyChangeSupport to keep your windows synced (or other purposes).

You may get java.io.NotSerializableException: javax.swing.GroupLayout while trying to serialize that specific class holding the PropertyChangeSupport. By changing PropertyChangeSupport to transient private PropertyChangeSupport variableName;,

while initializing you may resolve this error.

João Dias
  • 16,277
  • 6
  • 33
  • 45
MrBlade02
  • 11
  • 1