# Problem mit ObjectInputStreams



## derDude (29. Nov 2010)

Hallo,

ich bastle zurzeit auf Basis des Chat Servers im FAQ Bereich eine Client - Server Architektur. Welche über ObjectIn- und ObjectOutputstreams kommuniziert.

Dabei werden dem Server Objekte gesandt in denen Methoden enthalten sind die er ausführen soll. Dabei kommt es sporadisch zu Fehlern.

Serverseitig kommt es beim lesen des Input Streams zur java.lang.ClassCastException. Das lesen sieht  folgender massen aus:

```
...
while (true) {
   Object o = in.readObject();
   if (o != null) {
      this.ObjectHandling(o);
   }
}
...
```

Das schreiben Client seitig:

```
public String writeObject(Object o) {
		try {
			this.out.writeObject(o);
			this.out.flush();
			.....
```

Und Client seitig kommt es auch sporadisch zur EOF-exception ebenfalls beim lesen. Die Methoden sind äquivalent was die Methoden aufrufe bei den In- bzw. Outputstreams angeht.

Ich hoffe Ihr könnt mir weiter helfen. Wie gesagt ich konnte bisher noch keine Regelmäßigkeit feststellen.

Vielen Dank, schonmal


----------



## vladimir (29. Nov 2010)

Es sieht mir nach falschem Kasten von Objekten, die Meldung sagt es schon!


			
				derDude hat gesagt.:
			
		

> java.lang.ClassCastException


Kann es sein dass der Server und Client auf falsche Klassen kastet. 
Die serialisierten Objekte sind besonderes empfindlich, wenn Du Änderungen an den Klassen vornimmst musst Du aufpassen! Die Klassen müssen absolut identisch sein!


----------



## DerDude (29. Nov 2010)

Hi,

danke erstmal für die Antwort, die Klasse(n) sind definitiv identisch da sich Server und Client und somit auch die Protokoll klassen in einem Workspace befinden gibt es nur eine Instanz der jeweiligen Klasse. Desweiteren passiert immer in der gleichen Klasse die ClassCastException obwohl in dieser Klasse gar kein TypCast statt findet.

Hier mal die Klasse, laut Fehlermeldung versucht er das Suchwort als ArtikelList zu Casten wird aber nie gemacht.

```
public class ArtikelList extends EdpRequestExecuter {

	private static final long serialVersionUID = 5594251250415309121L;

	private String suchwort = "";

	public ArtikelList(String such) {
		this.suchwort = such;
	}

	@Override
	protected void run() {
		try {
			query.startQuery("2:1", "", "such=`" + suchwort, "such");
			Vector<String> nummern = new Vector<String>();
			for (int i = 0; i < 20 && query.getNextRecord(); i++) {
				nummern.add(query.getField(1));
				if (query.getField(1).equals(suchwort))
					break;
			}
			query.breakQuery();
			this.user.putObjectOut(new ArtikelListAntwort(nummern));
			return;
		} catch (InvalidQueryException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.user.putObjectOut(new EdpError("Fehler bei Listen anfrage"));
		return;
	}

}
```


----------



## vladimir (29. Nov 2010)

Sehe auf anhieb erstmal kein Fehler. Ich würd das ganze mal debugen! Setze ein Breakpoint kurz vor dem Exception wurf. Untersuche mal die Objekte die da übergeben werden. Vieleicht entdekst Du da noch was.


----------



## maki (29. Nov 2010)

> die Klasse(n) sind definitiv identisch da sich Server und Client und somit auch die Protokoll klassen in einem Workspace befinden gibt es nur eine Instanz der jeweiligen Klasse.


Nutzen denn Server & Client wirklich auch die Klassen aus dem Workspace oder einer davon etwa eine veraltete Jar?

Letzteres führt zu Problemen wenn keine serialVersionUID angegeben ist, dennd er Complier erzeugt bei jedem kompilieren eine neue, würde bedeuten dass Server & Client nicht mit derselben Klasse arbeiten.

Oder es gibt mehrere ClassLoader die dieselben Klassen laden, das führt auch zu deinem erwähnten Problem/Exception.


----------



## derDude (29. Nov 2010)

Hiho,

ich bin mir 100% sicher das sie die selbe bzw die aktuellste Fassung der Klasse nutzen. Ich habe diverse ausgaben eingebaut und diese Erscheinen auch. Der Fehler tritt wie gesagt sporadisch auf.

Hier ein Beispiel:

Server und Client sind frisch übersetzt und laufen. Ich trage im Client ein Suchwort für einen Artikel ein lasse die Abfrage ausführen alles funktioniert. Irgend wann und unabhängig von der Anzahl der Abfragen tritt die ClassCastException auf.

Nochmal zum Verständniss. Der Client erzeugt das Objekt per Konstruktor gibt ihm das Suchwort mit und das Objekt wird versandt . Der Server führt dann die run-Methode aus und liefert die Ergebnisse zurück an den Client.

Danke nochmal.


----------



## maki (29. Nov 2010)

Was steht denn genau im Stacktrace der ClassCastException?


----------



## FArt (29. Nov 2010)

Klassen, die physikalisch gleich sind und u.U. auch vom selben physikalischen Klassenpfad geladen wurden sind ungleich (und verursachen somit eine ClassCastException wenn gegenseitig Intanzen davon zugewiesen werden sollen), wenn sie von verschiedenen ClassLoadern geladen wurden.

Wären die Klassen bzgl. Marshalling/Unmarshalling inkompatibel, gäbe es andere Fehler.


----------



## derDude (2. Dez 2010)

Hiho,

ich versuche nun seit geraumer Zeit die Exception wieder auszulösen, das Problem ist das sie nur sehr sporadisch auftritt ich kann bis jetzt nicht sagen wann genau (dann würde ich ja den Fehler kennen.) Ich bin für weiter Tipps sehr dankbar.


----------



## derDude (8. Dez 2010)

Hi ho,

ich habe nun geraume Zeit herum probiert und konnte die Exception nicht wieder herbei führen ohne Quelltext Änderungen ... Nun habe ich ein anderes Problem wenn ich größere Objekte versenden möchte (~ 1MB) funktioniert dies nicht. Es wirkt so als ob der Server dabei stecken bleibt. Jemand eine Idee ? Der Quelltext beleibt gleich. Danke!


----------



## derDude (9. Dez 2010)

Heute kam sie wieder ...


```
java.lang.ClassCastException: cannot assign instance of de.finetech.edpclient.fertterminal.protokoll.artikel.ArtikelList to field de.finetech.edpclient.fertterminal.protokoll.artikel.ArtikelList.suchwort of type java.lang.String in instance of de.finetech.edpclient.fertterminal.protokoll.artikel.ArtikelList
	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.readObject(Unknown Source)
	at de.finetech.edpserver.utils.EdpUser.run(EdpUser.java:62)
```


----------

