java.io.InvalidClassException: classe locale incompatible:

j'ai créé le client et le serveur et j'ai ensuite ajouté une classe dans le côté client à des fins de sérialisation, puis je suis simplement allé dans le dossier du client dans mon disque dur et j'ai copié le coller à l'emplacement correspondant au serveur, tous les deux classname.class et classname.java respectivement.

cela a bien fonctionné dans mon propre ordinateur portable mais quand j'ai voulu continuer mon travail sur un autre système, quand j'ai ouvert les dossiers de projets et après que le client a essayé de se connecter au serveur, l'erreur suivante s'affiche:

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)

Ce qui se passe? Est-ce parce que j'ai lancé le programme avec une version plus ancienne de L'IDE?

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;
}
20
demandé sur belka 2012-04-30 09:22:27

5 réponses

Si une classe ne définit pas explicitement un private static final long serialVersionUID dans le code, il sera autogénéré, et il n'y a aucune garantie que différentes machines généreront le même id; il semble que c'est exactement ce qui s'est passé. En outre, si les classes sont différentes de quelque manière que ce soit (en utilisant différentes versions de la classe) l'autogénérisé serialVersionUID s sera également différent.

Serializable l'interface est docs:

Si une classe sérialisable ne pas déclarer explicitement un serialVersionUID, alors l'exécution de la sérialisation calculera un valeur pour cette classe basée sur divers aspects de la classe, comme décrit dans la spécification de sérialisation D'objet Java(TM). Cependant, il est fortement recommandé que toutes les classes sérialisables déclarent explicitement serialVersionUID valeurs, puisque la valeur par défaut est serialVersionUID le calcul est très sensible aux détails de la classe qui peuvent varier en fonction des implémentations du compilateur, et peut donc entraîner inattendu InvalidClassExceptions pendant la désérialisation. Par conséquent, pour garantir une cohérence serialVersionUID valeur à travers différentes implémentations de compilateurs java, une classe serialisable doit déclarer un < explicite!--2--> valeur. Il est également fortement conseillé explicite serialVersionUID les déclarations utilisent le private modificateur dans la mesure du possible, puisque ces déclarations ne s'appliquent qu'à la classe déclarant immédiatement--serialVersionUID les champs ne sont pas utiles comme membres hérités. Les classes Array ne peuvent pas déclarer un serialVersionUID, de sorte qu'ils toujours la valeur par défaut valeur calculée, mais l'exigence d'appariement serialVersionUID les valeurs sont supprimées pour les classes de tableaux.

Vous devez définir un serialVersionUID dans la définition de la classe, par exemple:

class MyClass implements Serializable {
    private static final long serialVersionUID = 6529685098267757690L;
    ...
31
répondu trutheality 2012-04-30 05:41:09

Une chose qui puisse arriver:

  • 1: vous créez vos données sérialisées avec une bibliothèque donnée A (version X)
  • 2: vous essayez alors de lire ces données avec la même bibliothèque A (mais la version Y)

ainsi, au moment de la compilation pour la version X, la JVM générera un premier numéro de série (pour la version X) et fera de même avec l'autre version Y (un autre numéro de série).

quand votre programme essaie de désérialiser les données, il ne peut pas parce que les deux classes n'ont pas le même identifiant de série et que votre programme n'a aucune garantie que les deux objets sérialisés correspondent au même format de classe.

en supposant que vous avez changé votre constructeur dans l'intervalle et cela devrait avoir du sens pour vous.

1
répondu belka 2018-03-14 09:52:48

je crois que cela se produit parce que vous utilisez les différentes versions de la même classe sur le client et le serveur. Il peut s'agir de différents champs de données ou méthodes

0
répondu Mark Bramnik 2012-04-30 05:29:35

le message d'exception indique clairement que les versions de classe, qui incluraient également les métadonnées de classe, ont changé au fil du temps. En d'autres termes, la structure de classe pendant la sérialisation n'est pas la même pendant la désérialisation. C'est ce qui est le plus probablement "en cours".

0
répondu nawazish-stackoverflow 2015-03-08 15:39:23

la sérialisation en java n'est pas censée être une persistance à long terme ou un format de transport - elle est trop fragile pour cela. Avec la moindre différence entre class bytecode et JVM, vos données ne sont plus lisibles. Utilisez XML ou JSON data-binding pour votre tâche ( XStream est rapide et facile à utiliser, et il ya une tonne d'alternatives)

0
répondu Konstantin Pribluda 2016-09-20 14:10:49