2016-12-05 3 views
-1

Dieser Socket empfängt weiterhin einige alte Objekte und neue Objekte mit gleichen Namen. Allerdings, wenn ich readObject direkt verwendet, wird es schwerwiegende Ausnahme ausgelöst. Einige von uns würden vorschlagen, altes Objekt zu ignorieren oder den alten Objektcode zu ändern. Dies ist für mich nicht möglich, Client-Codes zu ändern. Ich muss die Abwärtskompatibilität behandeln.Java-Abwärtskompatibilität: Wie liest readObject() gleiche Klassennamenobjekte mit unterschiedlicher serialVersionUID?


Socket s = ss.accept(); 
ObjectInputStream lvStream = new ObjectInputStream(s.getInputStream()); 
Object lvObject = lvStream.readObject(); 

// The old class but released (I cannot change it) 
public class Apple extends HashMap<String, String> { 
    private static final long serialVersionUID = 1L; 
} 
// The old class but released (I cannot change it) 
public class Apple extends HashMap<String, String> { 
    private static final long serialVersionUID = 2L; 
} 

// The new class in my local (1L or 2L still would not solve the issue easily) 
public class Apple extends HashMap<String, String> { 
    private static final long serialVersionUID = 2L; 
} 

an der Linie von readObject-(), Ich habe diese schwerwiegende Ausnahme:

java.io.InvalidClassException lokale Klasse unvereinbar: stream classdesc serialVersionUID = 1, lokale Klasse serialV ersionUID = 2

Wie konnte ich diese zwei Arten von Apple-Objekten Daten (die Hashmap) lesen?

Vielen Dank.

+4

hilft "Sie sind völlig gleich" - nein, sie sind in verschiedenen Paketen, nach zu deinem Kommentar. Der vollständig qualifizierte Klassenname ist in der Serialisierung (und im Allgemeinen) wichtig. –

+0

Fragen Sie, wie man ein serialisiertes Objekt einer Klasse als eine Instanz der anderen Klasse liest? – qxz

+2

Sie sind zwei verschiedene Arten. Die serielle UID-Version hat damit nichts zu tun. Wirf entweder auf "HashMap" und lies seine Einträge. – erickson

Antwort

-1

Solange wir die Object verlängern ,

wir haben Zugang SerialVersionUID zu streamen mit lokalen SerialVersionUID zu vergleichen.


Socket s = ss.accept(); 
// use the extended ObjectInputStream (DecompressibleInputStream) 
DecompressibleInputStreamlvStream = new DecompressibleInputStream(s.getInputStream()); 
Object lvObject = lvStream.readObject(); 

import java.io.IOException; 
import java.io.InputStream; 
import java.io.InvalidClassException; 
import java.io.ObjectInputStream; 
import java.io.ObjectStreamClass; 

public class DecompressibleInputStream extends ObjectInputStream { 

    public DecompressibleInputStream(InputStream in) throws IOException { 
     super(in); 
    } 

    protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException { 
     ObjectStreamClass resultClassDescriptor = super.readClassDescriptor(); 
     Class<?> localClass; 
     try { 
      localClass = Class.forName(resultClassDescriptor.getName()); 
     } catch (ClassNotFoundException e) { 
      System.err.println("No local class for " + resultClassDescriptor.getName()); 
      return resultClassDescriptor; 
     } 
     ObjectStreamClass localClassDescriptor = ObjectStreamClass.lookup(localClass); 
     if (localClassDescriptor != null) { 
      final long localSUID = localClassDescriptor.getSerialVersionUID(); 
      final long streamSUID = resultClassDescriptor.getSerialVersionUID(); 
      if (streamSUID != localSUID) { 
       System.err.println("Potentially Fatal Deserialization Operation."); 
       resultClassDescriptor = localClassDescriptor; 
      } 
     } 
     return resultClassDescriptor; 
    } 
} 

hoffen, dass es

(Kredite an diese post)

0

Java: Wie kann readObject() lesen zwei Klassen mit verschiedenen serialVersionUID?

Einfach. Sie sind verschiedene Klassen. Warum sollte es nicht?

Es gibt zwei Klassen mit demselben Namen, die sich jedoch in serialVersionUID unterscheiden.

Sie sind also verschiedene Klassen. Ihre Frage?

Ich habe diese schwerwiegende Ausnahme:

java.io.InvalidClassException local class incompatible : stream classdesc serialVersionUID = 2, local class serialVersionUID = 1 

, die nicht das Geringste mit zwei Klassen mit dem gleichen Namen in verschiedenen Paketen hat, etwas zu tun. Es bedeutet, dass Sie eine Version dieser Klasse mit serialVersionUID = 2 am Sender und eine andere Version mit serialVersionUID = 1 am Empfänger bereitgestellt haben. Soution: Tu das nicht. Stellen Sie die gleiche Version bereit: in diesem Fall die Version mit 2, wie sie im Stream enthalten ist. Im Allgemeinen sollten Sie nicht ändern serialVersionUID Werte ohne zu wissen genau was Sie tun.

In meinem Fall gibt es zwei Versionen, die Klasse zu mir senden. 1L und 2L.

Nein, gibt es nicht. Es gibt eine Version, die sendet, 2L, und eine andere Version, die 1L empfängt. Tu das nicht.

Verwandte Themen