java.io.InvalidClassException: lokale Klasse inkompatibel:

Lesezeit: 5 Minuten

Benutzeravatar von lonesome
einsam

Ich habe Client und Server erstellt und dann eine Klasse auf der Client-Seite für Serialisierungszwecke hinzugefügt, bin dann einfach in den Ordner des Clients auf meiner Festplatte gegangen und habe ihn an den entsprechenden Speicherort des Servers kopiert und eingefügt, beides classname.class und classname.java beziehungsweise.

Es funktionierte gut auf meinem eigenen Laptop, aber als ich meine Arbeit auf einem anderen System fortsetzen wollte, wenn ich die Projektordner öffnete 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;
}

Benutzeravatar von trutheality
Wahrhaftigkeit

Wenn eine Klasse a nicht explizit definiert private static final long serialVersionUID im Code wird es automatisch generiert, und es gibt keine Garantie dafür, dass verschiedene Computer dieselbe ID generieren; es sieht so aus, als wäre genau das passiert. Auch wenn sich die Klassen in irgendeiner Weise unterscheiden (unter Verwendung verschiedener Versionen der Klasse), wird die automatisch generiert serialVersionUIDs wird auch anders sein.

Von dem Serializable Schnittstelle Dokumente:

Wenn eine serialisierbare Klasse a nicht explizit deklariert serialVersionUIDdann berechnet die Serialisierungslaufzeit einen Standardwert serialVersionUID Wert für diese Klasse basierend auf verschiedenen Aspekten der Klasse, wie in der Java(TM) Object Serialization Specification beschrieben. Wie auch immer es ist wärmstens empfohlen die alle serialisierbaren Klassen explizit deklarieren serialVersionUID Werte, seit der Voreinstellung serialVersionUID Die Berechnung ist sehr empfindlich gegenüber Klassendetails, die je nach Compilerimplementierung variieren können und daher zu unerwarteten Ergebnissen führen können InvalidClassExceptions während der Deserialisierung. Daher, um eine konsistente zu gewährleisten serialVersionUID -Wert über verschiedene Java-Compiler-Implementierungen hinweg muss eine serialisierbare Klasse einen expliziten deklarieren serialVersionUID Wert. Es wird auch ausdrücklich darauf hingewiesen serialVersionUID Deklarationen verwenden die private Modifikator wo möglich, da solche Deklarationen nur für die unmittelbar deklarierende Klasse gelten–serialVersionUID -Felder sind als geerbte Elemente nicht nützlich. Array-Klassen können keine explizit deklarieren serialVersionUIDalso haben sie immer den berechneten Standardwert, aber die Anforderung für den Abgleich serialVersionUID Für Array-Klassen wird auf values ​​verzichtet.

Sie sollten a definieren serialVersionUID in der Klassendefinition, zB:

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

  • wie passt man die serialVersionUID in der Definition an?

    – einsam

    30. April 2012 um 5:36 Uhr


  • Das ist merkwürdig. Ich würde noch einmal überprüfen, ob beide Seiten die neueste Version der Klasse verwenden.

    – Wahrhaftigkeit

    30. April 2012 um 6:19 Uhr

  • Ich habe sogar zwei neue Projekte mit demselben Namen erstellt und die Klassen von Anfang an erstellt, aber es passiert immer noch

    – einsam

    30. April 2012 um 6:39 Uhr

  • Versuchen Sie, die Projektausgaben zu bereinigen (.class Dateien, die zur Kompilierzeit generiert wurden) und die Projekte neu erstellen (neu kompilieren).

    – Jair

    30. April 2012 um 6:47 Uhr

  • @EJP Der Versuch, die SUID einer anderen Version der Klasse zuzuordnen, ist nicht ratsam. Hier war es richtig, die Klasse an beiden Enden zu aktualisieren.

    – Wahrhaftigkeit

    30. April 2012 um 18:48 Uhr

Eines 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

Daher generiert die JVM zur Kompilierzeit für die Version X eine erste Serien-ID (für Version X) und macht dasselbe 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 Seriennummer haben und Ihr Programm nicht garantiert, dass die beiden serialisierten Objekte demselben Klassenformat entsprechen.

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

Wenn Sie die Eclipse-IDE verwenden, überprüfen Sie Ihre Debug/Run-Konfiguration. Wählen Sie auf der Registerkarte Classpath das Runner-Projekt aus und klicken Sie auf die Schaltfläche Bearbeiten.
Nur exportierte Einträge einbeziehen muss überprüft werden.

Versuchen Sie, die Ausgabedatei zu löschen/umzubenennen und eine neue zu erstellen, wenn Sie während des Testens ein Objekt gespeichert hatten. Ich hatte diesen Fehler, weil ich Daten in dieselbe Datei in zwei verschiedenen jFrame-Klassen serialisiert hatte.

Ich glaube, das passiert, weil Sie die verschiedenen Versionen derselben Klasse auf Client und Server verwenden. Das können unterschiedliche Datenfelder oder Methoden sein

Benutzeravatar von nawazish-stackoverflow
nawazish-Stapelüberlauf

Die Ausnahmemeldung spricht eindeutig dafür, dass sich die Klassenversionen, die auch die Klassenmetadaten enthalten würden, im Laufe der Zeit geändert haben. Mit anderen Worten, die Klassenstruktur während der Serialisierung ist nicht dieselbe wie während der Deserialisierung. Das ist es, was höchstwahrscheinlich “vor sich geht”.

Benutzeravatar von jpaugh
jpaugh

Die Serialisierung in Java ist nicht als langfristiges Persistenz- oder Transportformat gedacht – dafür ist es zu zerbrechlich. 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 Menge Alternativen)

  • Ich kann der Persistenz bis zu einem gewissen Grad zustimmen, aber es ist nichts falsch daran, die Java-Serialisierung als Transportformat zu verwenden. Es ist zu anfällig, wenn man die Konzepte der Java-Serialisierung nicht kennt serialVersionUID‘s.

    – Sanjay T. Sharma

    30. April 2012 um 6:43 Uhr


  • Es ist nicht wirklich. Vielleicht sehen wir die Welt der ‘Java-Serialisierung’ nur mit einer andersfarbigen Brille. Außerdem ist es so ziemlich die einzige Option bei der Verwendung von RMI. Ich sehe auch, dass Sie einen Kommentar zu “Projektmanager, der etwas häutet” abgegeben haben, der später herausgeschnitten wurde …

    – Sanjay T. Sharma

    30. April 2012 um 8:47 Uhr

  • “Kleinster Unterschied in Klasse Bytecode und JVM und Ihre Daten sind nicht mehr lesbar”. Das ist einfach nicht wahr. Siehe den Abschnitt Objektversionierung der Objektserialisierungsspezifikation.

    – Benutzer207421

    30. April 2012 um 10:06 Uhr

  • @EJP Hier ist ein Link: Versionierung von serialisierbaren Objekten

    – jpaugh

    20. September 2016 um 14:12 Uhr


1436220cookie-checkjava.io.InvalidClassException: lokale Klasse inkompatibel:

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy