# bean + serialisierung + serialVersionUID



## jollyroger (11. Okt 2006)

Liebe Leute, 

ich hab seit Stunden ein Problem welches mich in den Wahnsinn treibt und hoffe ihr könnt mir helfen....

Folgendes:

Ich hab folgendes Bean namens TrcsProcessConfigBean :


```
public class TrcsProcessConfigBean implements Serializable{
 
	protected String procName;
	protected String oStackName;
	protected String oStackNodeName;
	
	public String getOStackName() {
		return oStackName;
	}
	public String getProcName() {
		return procName;
	}
	public String getOStackNodeName() {
		return oStackNodeName;
	}
	
	public TrcsProcessConfigBean(String procName, String oStackName, String oStackNodeName) {
		this.procName = procName;
		this.oStackName = oStackName;
		this.oStackNodeName = oStackNodeName;
	}
}
```

Von diesem erbt nun ein anderes Bean namens TrcsProcessConfigBeanConv :


```
public class TrcsProcessConfigBeanConv  extends TrcsProcessConfigBean implements Serializable {

	private String iStackName;
	private String iStackNodeName;

	public String getIStackNodeName() {
		return iStackNodeName;
	}

	public String getIStackName() {
		return iStackName;
	}
	
	public TrcsProcessConfigBeanConv(String procName, String oStackName, String oStackNodeName, String iStackName, String iStackNodeName ) {
		super(procName, oStackName, oStackNodeName);
		this.iStackName = iStackName;
		this.iStackNodeName = iStackNodeName;
	}
}
```

Dieses TrcsProcessConfigBeanConv will ich nun serialisieren und wieder deserialisieren, dazu hab ich mir folgende einfache Main-Methode geschrieben:




```
public class TestSerializingCfgBean {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		TrcsProcessConfigBeanConv cfgBean = new TrcsProcessConfigBeanConv("behemoth_process","output_stack_30","foo", "bar", "foobar");
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		try {

// serialize
			ObjectOutputStream oos = new ObjectOutputStream(baos);
			oos.writeObject(cfgBean);
			oos.flush();
			oos.close();

			String s = new String(baos.toString());
			System.out.println("TrcsProcessConfigBean serialized into a string: "+ s);

// deserialize

			ByteArrayInputStream bais = new ByteArrayInputStream(s.getBytes());
			ObjectInputStream ois = new ObjectInputStream(bais);
			TrcsProcessConfigBeanConv cfgBean2 = (TrcsProcessConfigBeanConv) ois.readObject();
			ois.close();

		
		} catch (IOException e) {
			System.out.println("IO Exception:" + e.getMessage());
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			System.out.println("ClassNotFound Exception:" + e.getMessage());
			e.printStackTrace();
		}
	}
}
```

Führe ich das aus erhalte ich :


```
IO Exception:de.trcsystem.process.TrcsProcessConfigBean; local class incompatible: stream classdesc serialVersionUID = 2718507660599967685, local class serialVersionUID = 2718507660599991749
java.io.InvalidClassException: de.trcsystem.process.TrcsProcessConfigBean; local class incompatible: stream classdesc serialVersionUID = 2718507660599967685, local class serialVersionUID = 2718507660599991749
	at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
	at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
	at java.io.ObjectInputStream.readClassDesc(Unknown Source)
	at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
	at java.io.ObjectInputStream.readClassDesc(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.trcsystem.testing.TestSerializingCfgBean.main(TestSerializingCfgBean.java:36)
```

Zeile 36 ist diese


```
TrcsProcessConfigBeanConv cfgBean2 = (TrcsProcessConfigBeanConv) ois.readObject();
```

Zeile der Main-Methode, also am Ende der Deserialisierung.

So, das verstehe ich schon mal nicht, ich setzte ja in den beans keine serialVersionUID.
Aber eclipse zeigt mir das als Warning bei den Bean-Klassen an:


```
The serializable class TrcsProcessConfigBean does not declare a static final serialVersionUID field of type long
```

ok, dann hab ich auf die Warnung geklickt und eclipse bietet mir nun als Auswahlmöglichkeit:


```
Add generated serial version ID
```

Das hab ich dann in beiden bean-Klassen angeklickt, die sehen nun so aus:


```
public class TrcsProcessConfigBean implements Serializable{
 

	private static final long serialVersionUID = -5590868576506217927L;
	
	protected String procName;
	protected String oStackName;
	protected String oStackNodeName;
	
	public String getOStackName() {
		return oStackName;
	}
	public String getProcName() {
		return procName;
	}
	public String getOStackNodeName() {
		return oStackNodeName;
	}
	
	public TrcsProcessConfigBean(String procName, String oStackName, String oStackNodeName) {
		this.procName = procName;
		this.oStackName = oStackName;
		this.oStackNodeName = oStackNodeName;
	}
}
```

und so:


```
public class TrcsProcessConfigBeanConv  extends TrcsProcessConfigBean implements Serializable {

	private static final long serialVersionUID = 2718507660599991749L;

	private String iStackName;
	private String iStackNodeName;

	public String getIStackNodeName() {
		return iStackNodeName;
	}

	public String getIStackName() {
		return iStackName;
	}
	
	public TrcsProcessConfigBeanConv(String procName, String oStackName, String oStackNodeName, String iStackName, String iStackNodeName ) {
		super(procName, oStackName, oStackNodeName);
		this.iStackName = iStackName;
		this.iStackNodeName = iStackNodeName;
	}
}
```

Es ist also jeweils nur ein Feld hinzugekommen.

Führe ich aber nun meine main-Methode aus, kriege ich:


```
IO Exception:de.trcsystem.process.conv.TrcsProcessConfigBeanConv; local class incompatible: stream classdesc serialVersionUID = 2718507660599967685, local class serialVersionUID = 2718507660599991749
java.io.InvalidClassException: de.trcsystem.process.conv.TrcsProcessConfigBeanConv; local class incompatible: stream classdesc serialVersionUID = 2718507660599967685, local class serialVersionUID = 2718507660599991749
	at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
	at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
	at java.io.ObjectInputStream.readClassDesc(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.trcsystem.testing.TestSerializingCfgBean.main(TestSerializingCfgBean.java:36)
```

Also genau die gleiche Fehlermeldung wie vorher....
Was ich auch nicht verstehe ist, das die in der Fehlermeldungen genannten serialVersionUID nicht mit dem übereinstimmen was in meinen Klassen steht:

in TrcsProcessConfigBean steht:


```
private static final long serialVersionUID = -5590868576506217927L;
```

Und in TrcsProcessConfigBeanConv:


```
private static final long serialVersionUID = 2718507660599991749L;
```

in der Fehlermeldung hingegen:


```
tream classdesc serialVersionUID = 2718507660599967685, local class serialVersionUID = 2718507660599991749
```

Was soll das? Muss ich das verstehen? 
Was kann ich tun?

Danke für alle Tips im Voraus!


----------



## SlaterB (11. Okt 2006)

das muss was mit den ganzen Umwandlungen zu tun haben,
da wird die Versions-ID irgendwann verfälscht,
z.B. abhängig davon ob ein byte oder long mit Vorzeichen oder ohne Vorzeichen interpretiert wird,
oder sowas in der Art 

mit kleinen VersionsIds wie 1,2,3, < 10 Stellen scheint es problemlos zu funktionieren

ebenfalls zu funktionieren 'scheint' es bei mir bei Angabe eines Encoding/ CharSets:

String s = new String(baos.toString("ISO-8859-1"));
ByteArrayInputStream bais = new ByteArrayInputStream(s.getBytes("ISO-8859-1"));

aber sieh das höchstens als 'Probieren bis es mal zufällig geht' an,
keine Garantie


----------



## jollyroger (12. Okt 2006)

Also erst mal ein dickes Dankeschön an SlaterB!

Es funktioniert jetzt nachdem ich die ID selber vergeben habe, also sowas wie "111", "222" usw....

Aber eine Frage noch: 

Ist das nun ein Bug in Java oder in Eclipse?

Ich hab bezüglich  eclipse gegoogelt nach "eclipse bug serialization suid" und dazu auch einiges gefunden, aber nichts was irgendwie genau dieses Problem beschreibt.

Sollte man einen bugreport schreiben? Oder ist das schon passiert? Oder übersehe ich was?


----------



## SlaterB (12. Okt 2006)

wie ich bereits geschrieben habe (kann man das nicht rauslesen?)
würde ich den Fehler eher bei dir ansiedeln,

Object, byte[], String, byte[], Object
ist nun mal nicht ganz trivial, sicherlich auch abhängig vom lokalen Betriebssystem, Spracheinstellungen,
was weiß ich nicht alles

ich stimme dir zu, dass dein Code 'eigentlich' ganz normal aussieht und eine korrekt Ausführung auch ohne Angabe von 'ISO-8859-1' wüschenswert ist,

was nun dafür oder dagegen spricht/ woher der Fehler eigentlich genau kommt wage ich aber nicht zu beurteilen, du sicher noch weniger,
Bugs anlegen würde ich also den Profis überlassen, die bei solch allgemeinen Code sicherlich schon vorbeigekommen sind,

gegen Nachfragen auch in Bugreport-Foren (falls es die gibt) spricht natürlich nix


---------

versuchs doch mal ohne Eclipse,
mit Komandozeile javac/ java, dann sieht du ob es was mit Eclipse zu tun hat (falls es ohne Eclipse klappt),

würde mich stark überraschen, aber habe dennoch keine Lust, es selber zu testen


----------

