wake-up-neo.com

java.io.InvalidClassException: lokale Klasse inkompatibel:

Ich erstellte Client und Server und fügte dann auf der Clientseite eine Klasse hinzu, um sie zu serialisieren. Dann ging ich einfach in den Ordner des Clients auf meiner Festplatte und kopierte ihn in den entsprechenden Speicherort des Servers, jeweils classname.class und classname.Java.

Bei meinem eigenen Laptop hat es gut funktioniert. Als ich jedoch meine Arbeit auf einem anderen System fortsetzen wollte, beim Öffnen der Projektordner und nachdem der Client versucht, eine Verbindung zum Server herzustellen, wird der folgende Fehler 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?

BEARBEITEN

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;
}
21
lonesome

Wenn eine Klasse einen private static final long serialVersionUID nicht explizit im Code definiert, wird sie automatisch generiert, und es gibt keine Garantie, dass verschiedene Maschinen dieselbe ID generieren. Es sieht so aus, als sei genau das passiert, was passiert ist ..__ Auch wenn die Klassen in irgendeiner Weise unterschiedlich sind (unter Verwendung verschiedener Versionen der Klasse), werden auch die automatisch generierten serialVersionUIDs unterschiedlich sein.

Aus der Serializable-Schnittstelle docs :

Wenn eine serialisierbare Klasse einen serialVersionUID nicht explizit deklariert, berechnet die Serialisierungslaufzeit einen serialVersionUID-Standardwert für diese Klasse basierend auf verschiedenen Aspekten der Klasse, wie in der Java (TM) Object Serialization Specification beschrieben. Es ist jedoch dringend empfohlen, dass alle serialisierbaren Klassen explizit serialVersionUID-Werte deklarieren, da die Standardberechnung serialVersionUID sehr empfindlich auf Klassendetails reagiert, die je nach Implementierung des Compilers variieren können und daher während der Deserialisierung zu unerwarteten InvalidClassExceptions-Werten führen kann. Um einen konsistenten serialVersionUID-Wert über verschiedene Java-Compiler-Implementierungen hinweg zu gewährleisten, muss eine serialisierbare Klasse einen expliziten serialVersionUID-Wert deklarieren. Es wird außerdem dringend empfohlen, dass explizite serialVersionUID-Deklarationen soweit möglich den Modifizierer private verwenden, da solche Deklarationen nur für die unmittelbar deklarierenden Klasse gelten - serialVersionUID-Felder sind als geerbte Mitglieder nicht nützlich. Array-Klassen können keine expliziten serialVersionUID-Werte deklarieren. Daher haben sie immer den berechneten Standardwert. Die Anforderung für den Abgleich von serialVersionUID-Werten für Array-Klassen wird jedoch weggelassen.

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

class MyClass implements Serializable {
    private static final long serialVersionUID = 6529685098267757690L;
    ...
35
trutheality

Eine Sache, die hätte passieren können:

  • 1: Sie erstellen Ihre serialisierten Daten mit einer bestimmten Bibliothek A (Version X).
  • 2: Sie versuchen dann, diese Daten mit derselben Bibliothek A (aber Version Y) zu lesen.

Zum Zeitpunkt der Kompilierung für die Version X generiert die JVM daher eine erste Serien-ID (für Version X) und dies auch mit der anderen Version Y (einer anderen Serien-ID).

Wenn Ihr Programm versucht, die Daten zu deserialisieren, ist dies nicht möglich, da die beiden Klassen nicht dieselbe Serien-ID haben und Ihr Programm keine Garantie dafür gibt, dass die beiden serialisierten Objekte demselben Klassenformat entsprechen.

Angenommen, Sie haben Ihren Konstruktor zwischenzeitlich geändert und dies sollte für Sie sinnvoll sein.

2
belka

Die Ausnahmemeldung besagt eindeutig, dass sich die Klassenversionen, die auch die Metadaten der Klasse enthalten würden, im Laufe der Zeit geändert haben. Mit anderen Worten, die Klassenstruktur während der Serialisierung ist während der Deserialisierung nicht gleich. Dies ist, was höchstwahrscheinlich "los" ist.

Ich glaube, dass dies der Fall ist, weil Sie die verschiedenen Versionen derselben Klasse auf Client und Server verwenden

0
Mark Bramnik

Wenn Sie oc4j zum Bereitstellen des Ohrs verwenden.

Stellen Sie sicher, dass Sie im Projekt den richtigen Pfad für deploy.home = festgelegt haben

Sie können deploy.home in der Datei common.properties finden

Das oc4j muss die neu erstellte Klasse im Ohr neu laden, damit die Serverklasse und die Clientklasse dieselbe serialVersionUID haben

0
Mr Big

Serialisierung in Java ist nicht als Langzeitpersistenz oder Transportformat gedacht - dafür ist es zu zerbrechlich. Mit dem geringsten Unterschied in Klassenbytecode und JVM sind Ihre Daten nicht mehr lesbar. Verwenden Sie XML- oder JSON-Datenbindung für Ihre Aufgabe ( XStream ist schnell und einfach zu verwenden, und es gibt eine Vielzahl von Alternativen)

0