简体   繁体   中英

Java: Serialization doesn't work for the second time

I have a server on which I keep track of some data. When I connect to the server with the administrator application to check out the current state of the data. I use a refresh rate of 5 seconds. The first time the server sends the data, it works. But the second time, when the data changed, the admin-side does not receive the up-to-date data. I'm sending the data, wrapped in a class, through an ObjectOutputStream and ObjectInputStream:

This is the wrapper class for the data:

public class Leerling implements Serializable {

    public int llnID;

    public String naam;
    public String voornaam;
    public String klas;
    public int klasNummer;
    public Date geboorteDatum;

    public String getFullName()
    {
        return voornaam + " " + naam;
    }

    @Override
    public String toString() {
        return "Leerling{" + "llnID=" + llnID + ", naam=" + naam + ", voornaam=" + voornaam + ", klas=" + klas + ", klasNummer=" + klasNummer + ", geboorteDatum=" + geboorteDatum + '}';
    }

}


public class SLeerling extends Leerling implements Serializable{

    public boolean voted;
    public int vote = -2;
}

What I tried is before reading the Object from the stream to call System.gc(); to make sure the object old object is not longer in memory. But without success.

Does someone know what the exact problem is? And how to make it possible to get the real up-to-date data?

Thanks in advance.


A second example of the problem:

I have again a wrapper class for some other data (It is an inner class):

public static class MonitorResponse implements Serializable
{
    public int numberOfLLN;
    public int blocked;
    public int blancos;
    public List<Integer> votes;
}

When I send the data the first time, it works. But the second time I send it (to update it), everything EXCEPT the List<Integer> votes is updated. So votes isn't refreshed. Then I solved it a bit tricky by replacing the List by an array:

public static class MonitorResponse implements Serializable
{
    public int numberOfLLN;
    public int blocked;
    public int blancos;
    public Integer[] votes;
}

And this works perfect. Strange if you ask me. The the other part of the code I changed almost nothing... (except to implement the array instead of the List)

It's probably the ObjectOutputStream causing the trouble.

If you use a single ObjectOutputStream object on the server then you need to make sure you call reset on it, otherwise it will write shared references to previously-written objects. This sounds like what you are seeing.

To illustrate the problem:

class BrokenServer {
    void sendBrokenVoteData(ObjectOutputStream out) {
        out.writeObject(votes);
        changeVoteData(votes);
        out.writeObject(votes); // Writes a shared reference to "votes" WITHOUT updating any data.
    }
}

class FixedServer {
    void sendFixedVoteData(ObjectOutputStream out) {
        out.writeObject(votes);
        changeVoteData(votes);
        out.reset(); // Clears all shared references.
        out.writeObject(votes); // Writes a new copy of "votes" with the new data.
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM