Class that cannot be serialized

Asked

Viewed 127 times

1

Next, I’m studying a project involving javaWeb, with jsf+primefaces. I’m using the apache tomcat 7. The problem is happening when starting the apache service to then test my application, in which the error I identified was the following:

fev 25, 2016 2:42:56 PM org.apache.catalina.session.StandardSession writeObject
ADVERTÊNCIA: Cannot serialize session attribute contatoController for
session 707B3CF6A468012EFA4220B84449EB6B java.io.NotSerializableException: Bean.ContatoBean

My Contactobean class is as follows:

public class ContatoBean implements Serializable{
    private int id;
    private String nome;
    private String endereco;
    private String cidade;
    private String uf;
    private String telefone;
    private String celular;
    private String email;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getEndereco() {
        return endereco;
    }

    public void setEndereco(String endereco) {
        this.endereco = endereco;
    }

    public String getCidade() {
        return cidade;
    }

    public void setCidade(String cidade) {
        this.cidade = cidade;
    }

    public String getUf() {
        return uf;
    }

    public void setUf(String uf) {
        this.uf = uf;
    }

    public String getTelefone() {
        return telefone;
    }

    public void setTelefone(String telefone) {
        this.telefone = telefone;
    }

    public String getCelular() {
        return celular;
    }

    public void setCelular(String celular) {
        this.celular = celular;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

}

Even though I’m removing the implements serializable, he keeps making mistakes, someone knows what could be?

  • You have a long serialVersionUID declared? or to Annotation @Suppresswarnings("")??

  • Don’t have Thiago, would you need to put in this class? In case it would be private long serialVersionUID = 1; ???

  • An example: private Static final long serialVersionUID = -1931519544424229043L;

2 answers

1

When an object is serialized in Java, this byte sequence, in addition to containing its nontransient instance attributes, carries with it a number that identifies the "version" of the class that was used during the process.

This is the so-called serialVersionUID, i.e., the serialization version indenter of a class.

This number is used to know if the object we are recovering is from a version "compatible" with the version of the class that was used when serializing the object: in other words, the files .class do not necessarily have to be the same for the serialization process to occur successfully.

Example:

public class ContatoBean implements Serializable{
 private static final long serialVersionUID = -1931519544424229043L;

// seu código..
}
  • The problem is I don’t know how to figure out this correct serial :/

  • Did you try to put some value? type -1L??

1

Class name be logged in as Bean.ContatoBean suggests that she is an inner class (Inner class), that is to say, ContatoBean is stated within Bean.

I also assume that the outer class has an attribute like ContatoController.

For example:

public class Bean {
    ContatoController  contatoController;
    ...
    public class ContatoBean {
        ...
    }
}

The problem with internal classes is that they keep an implicit reference to the outermost class, so you can access its attributes. The side effect of this, in your case, is that Java is trying to serialize the external class along with the internal class, because of the implicit reference.

There are two ways to solve this:

1. Static internal class

Simply change the inner class to be static. This makes it unable to access the external class attributes, but at least you will get the desired result.

From there it will be a class like any other, accessible by other classes without having an external class instance.

Example:

public class Bean {
    ContatoController  contatoController;
    ...
    public static class ContatoBean {
        ...
    }
}

2. Outsourcing the internal class

Move the internal class to a normal class in a separate file.

I recommend this approach when working with frameworks like JSF or Spring, which instantiate classes using reflection.

Although they work with inner classes most of the time, there are always some cases where it doesn’t work well, like the one you came across.

This is because inner classes function somewhat differently from a normal class. Some of the details you’ve noticed from what I wrote, like the internal reference and also the class name contain the external class name.

  • Luiz, in the sentence "The side effect of this, in your case, is that Java is trying to serialize the outer class together with the outer class because of the implicit reference.", would not be "...the external class together with the internal(...)" or the other way round?

  • @Exact Diegof. Thank you.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.