0

Hi guys I am getting this problem on my console, but only appear sometimes.. not always.. I would like your help if possible, thanks

Error:

Exception in thread "Thread-2" java.lang.ClassCastException: cannot assign instance of java.lang.String to field Element.posElement of type java.awt.Point in instance of Personagem
    at java.io.ObjectStreamClass$FieldReflector.setObjFieldValues(Unknown Source)
    at java.io.ObjectStreamClass.setObjFieldValues(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readArray(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readArray(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at LaunchCliente$receberDoServidor.run(LaunchCliente.java:332)

and here is my code, when I am trying to read the object :

Object a = inputStream.readObject();


if(a instanceof Mapa){
    Mapa novo = (Mapa) a;
    if(launchJogo.getListaObstaculos().size() == 0)
    launchJogo.setLista(novo.getListaObstaculos());
    launchJogo.setListaPers(novo.getListaPersonagens());
    launchJogo.setElements(novo.getElements());
    launchJogo.getFrame().pack();
}
else if(a instanceof logout){
    if(launchJogo != null)
    launchJogo.getFrame().dispose();
    novo.close();
}
else if(a instanceof updateList){
    Vector<String> novo = ((updateList) a).getUpdateList();
    if(novo.size() != 0){
        if(!nomeUtilizador.isEnabled()){
            modeloDaLista.clear();
            arrayDeJogos = new Vector&lt;String&gt;(novo);
            for (String x : arrayDeJogos) {
                modeloDaLista.addElement(x);
            }
            janela.validate();
        }
    }
    if(novo.size() == 0){
        modeloDaLista.clear();
    }
}
else if(a instanceof String){
    String b = a.toString();
    if(b.equals("COLOR:FALSE")){
        JOptionPane.showMessageDialog(c, "Essa cor já está em uso no jogo selecionado!" , "Cor já escolhida!",
        JOptionPane.WARNING_MESSAGE);
        launchJogo = null;
        cores.dispose();
        janela.setVisible(true);
    }
    else if(b.equals("CREATE:BUTTONSTART")){
        launchJogo.getOptions().showButton(true);
    }
    else if(b.equals("ACTIVE:BUTTONSTART")){
        if(!launchJogo.getOptions().isButtonEnabled()){
            launchJogo.getOptions().setBotaoState(true);
        }
    }
    else if(b.equals("COLOR:TRUE")){
        cores.dispose();
        out.writeObject(new addToAGame(corDoJogador, nomeJogador, jogoSelecionado));
        launchJogo = new LaunchJogo(launchCliente, jogoSelecionado, nomeJogador);
    }
    else if(b.equals("LAUNCH:GAME")){
        if(launchJogo != null)
        launchJogo.addPersonagemListener();
    }
}
} catch (ClassNotFoundException e) {
  System.out.println("Class not found!");
} catch (IOException e) {
  this.interrupt();
}

Thanks alot in advance guys, I would appreciate some help

2
  • What is there on line 332 in class LaunchCliente ? Commented Dec 11, 2011 at 12:29
  • Please indent the code to the right level so its more readable. Commented Dec 11, 2011 at 12:34

3 Answers 3

3

The error message is telling you that the object stream is encountering a runtime error while rebuilding a serialized object. The object state being deserialized has a String for a value of the field Element.posElement ... which ought to be a Point according to the version of the Element class that your application is using.

The problem is with the actual serialized objects that you are attempting to read. I suspect that some time in the past you have changed the type of the Element.posElement field from String to Point (or vice versa), and you are trying to deserialize an object created by the other version of the class to the one you are currently using.

Normally, the object reader would complain about incompatible versions, but I suspect that you have: - added serialVersionId constants to your classes, and - failed to update the serialVersionId for Element after making a change that makes the new version incompatible with the old one.


Another possibility (see @TInusTate's comment) is that there are multiple threads writing to a shared ObjectOutputStream instance without synchronizing properly. This can result in the bytes from different objects getting "mixed up".

You could get a similar effect if you did other things like:

  • Multiple ObjectOutputStream instances wrapping a shared OutputStream.
  • Multiple threads reading from the same ObjectInputStream.

In some cases, the solution is proper synchronization. In others, the problem is intractable. None of the stream classes are inherently thread-safe, and multiple threads multiplexing data over a single stream is a difficult problem, requiring considerable care.


You are going to need to find where these incompatible serialized objects are coming from and either get rid of them or (somehow) replace them. In the future, you need to be more careful whan making changes to classes that may have been serialized and persisted, etcetera.

(This kind of problem is one of the reasons why ObjectStream serialization can be problematic for persisting state.)

Sign up to request clarification or add additional context in comments.

2 Comments

Note that when reading from an socket inputstream you can receive this error when the outputstream sends serialized objects without proper synchronisation ie bytes from serialized objects get mixed up. Synchronizing access to objectoutputstream solves this.
Your comment was perfect. you should make this an answer to the question. It is a weird error to get and not much points to multiple writes to the stream at the same time. Making the write to stream method synchronized was perfect.
1

The error is quite obvious.

cannot assign instance of java.lang.String 
  to field Element.posElement of type java.awt.Point

At the point where the error occurs, you are trying to assign a String where a "awt.Point" is exspected.

The bad thing is that I'm not sure of the problem is in the code you pasted. Check line 332 of LaunchCliente.java.

You should be able to debug the issue and figure out which line it is.

1 Comment

Thanks for your reply! That line is when I try to read the object: Object a = inputStream.readObject(); But look I have many conditions, and I have all the cases that I can receive from server :s This error only appears sometimes..
0

First few points

  1. You don't have "a instance of Persongem"
  2. You are not capturing ClassCastException. May be capture it with as much information as you can.
  3. The problem is with the Serialized version of your class only. It has definitely been changed at least once for at least one data (data/row in lose terms).
  4. Thread does complicate the stuff. Have a test around it.

Resolution: The thing you can do is identify the data. alienate/correct/log and fail safely in such case.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.