2012-04-30 16 views
19

Ich habe Client und Server erstellt und dann eine Klasse in der Client - Seite für die Serialisierung hinzugefügt, dann ging einfach einfach in den Ordner des Clients auf meiner Festplatte und kopieren Sie es in die Serveradresse, sowohl classname.class als auch classname.java.java.io.InvalidClassException: lokale Klasse inkompatibel:

Es funktionierte gut in meinem eigenen Laptop, aber wenn ich wollte, dass meine Arbeit auf anderem System weiter, wenn ich die Projekte Ordner geöffnet und nach der Client mit dem Server zu verbinden versucht, die folgende Fehlermeldung angezeigt:

Exception in thread "main" java.io.InvalidClassException: projectname.clasname; local class incompatible: stream classdesc serialVersionUID = -6009442170907349114, local class serialVersionUID = 6529685098267757690 
    at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:562) 
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1582) 
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495) 
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731) 
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) 
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) 

Was ist los? Liegt es daran, dass ich das Programm mit einer älteren Version der IDE ausgeführt habe?

EDIT

import java.io.Serializable; 
import java.net.URL; 


public class KeyAdr implements Serializable{ 

     private static final long serialVersionUID = 6529685098267757690L; 


public URL adr; 
public String key; 


} 

Antwort

27

Wenn eine Klasse nicht explizit ein private static final long serialVersionUID im Code definieren wird es automatisch generiert werden, und es gibt keine Garantie, dass verschiedene Maschinen die gleiche ID erzeugen; Es sieht so aus, als wäre genau das passiert. Auch wenn die Klassen in irgendeiner Weise anders sind (mit verschiedenen Versionen der Klasse), werden die automatisch generierten serialVersionUID s auch anders sein.

Von der Serializable Schnittstelle der docs:

Wenn eine serializable Klasse nicht explizit ein serialVersionUID erklärt, dann wird die Serialisierung Laufzeit einen Standard serialVersionUID Werte für diese Klasse auf der Grundlage verschiedenen Aspekte der Klasse berechnen, wie beschrieben in der Java (TM) -Objektserialisierungsspezifikation. Es wird jedoch dringendserialVersionUIDserialVersionUID Werte ausdrücklich empfohlen, da die Standard serialVersionUID Berechnung sehr empfindlich für Klassendetails ist, die je nach Compilerimplementierungen variieren können, und daher unerwartete InvalidClassExceptions während der Deserialisierung führen können. Um einen konsistenten serialVersionUID Wert für verschiedene Java-Compiler-Implementierungen zu garantieren, muss eine serialisierbare Klasse daher einen expliziten Wert von serialVersionUID deklarieren. Es wird auch dringend empfohlen, dass explizite serialVersionUID Deklarationen den Modifikator private verwenden, wo dies möglich ist, da solche Deklarationen nur für die unmittelbar deklarierende Klasse gelten. serialVersionUID Felder sind nicht nützlich als geerbte Mitglieder. Array-Klassen können keine explizite serialVersionUID deklarieren, so dass sie immer den standardmäßig berechneten Wert haben, aber die Anforderung für übereinstimmende serialVersionUID Werte wird für Array-Klassen aufgehoben.

Sie sollen ein serialVersionUID in der Klassendefinition definieren, z.B .:

class MyClass implements Serializable { 
    private static final long serialVersionUID = 6529685098267757690L; 
    ... 
+0

Wie wird die serialVersionUID in der Definition angepasst? – lonesome

+0

immer noch gleiche Fehler passiert – lonesome

+0

Das ist seltsam. Ich würde überprüfen, dass beide Seiten die neueste Version der Klasse verwenden. – trutheality

0

Ich glaube, dies geschieht, weil die verschiedenen Versionen der gleichen Klasse auf Client und Server verwenden. Es kann verschiedene Datenfelder oder Methoden sein

0

Serialisierung in Java ist nicht als langfristige Persistenz oder Transportformat gemeint - es ist zu schwach dafür. Mit dem geringsten Unterschied in Klasse Bytecode und JVM sind Ihre Daten nicht mehr lesbar.Verwenden Sie XML-oder JSON-Datenbindung für Ihre Aufgabe (XStream ist schnell und einfach zu bedienen, und es gibt eine Tonne von Alternativen)

+2

Ich kann einem Grad für Persistenz zustimmen, aber es ist nichts falsch daran, Java Serialization als Transportformat zu verwenden. Es ist zu zerbrechlich, wenn man die Konzepte der Java-Serialisierung wie 'serialVersionUID' nicht kennt. –

+0

Es ist schon damals zerbrechlich. –

+0

Es ist nicht wirklich. Vielleicht sehen wir nur die Welt der "Java-Serialisierung" mit verschiedenfarbigen Gläsern. Außerdem ist es die einzige Option bei der Verwendung von RMI. Außerdem habe ich bemerkt, dass Sie einen Kommentar zum "Projektmanager, der etwas skintet" gemacht haben, der später herausgeschnitten wurde ... –

0

Die Ausnahmebedingungsnachricht spricht klar, dass die Klassenversionen, die die Klasse Metadaten enthalten würde , hat sich im Laufe der Zeit verändert. Mit anderen Worten, die Klassenstruktur während der Serialisierung ist während der Deserialisierung nicht dieselbe. Dies ist wahrscheinlich, was "vor sich geht".

Verwandte Themen