2012-04-30 17 views
19

Creé el cliente y el servidor y luego agregué una clase en el lado del cliente para propósitos de serialización, luego simplemente fui a la carpeta del cliente en mi disco duro y copié y pegué al ubicación correponder del servidor, ambos classname.class y classname.java respectivamente.java.io.InvalidClassException: clase local incompatible:

funcionó bien en mi propio ordenador portátil, pero cuando quería continuar mi trabajo en otro sistema, cuando abrí las carpetas de los proyectos y al cliente intenta conectarse al servidor, aparece el siguiente error:

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) 

¿Qué está pasando? ¿Es porque ejecuté el programa con una versión anterior del IDE?

EDITAR

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; 


} 

Respuesta

27

Si una clase no define explícitamente un private static final long serialVersionUID en el código que se genera automáticamente, y no hay garantía de que las diferentes máquinas generarán el mismo id; parece que eso es exactamente lo que sucedió. Además, si las clases son diferentes de alguna manera (utilizando diferentes versiones de la clase), las serialVersionUID autogeneradas también serán diferentes.

de la interfaz Serializabledocs:

Si una clase serializable no declara explícitamente un serialVersionUID, entonces el tiempo de ejecución de serialización calculará un valor predeterminado serialVersionUID para esa clase en base a varios aspectos de la clase, tal como se describe en la especificación de serialización de objetos Java (TM). Sin embargo, es recomienda encarecidamente que todas las clases serializables declaran explícitamente serialVersionUID valores, ya que el cálculo predeterminado serialVersionUID es altamente sensible a los detalles de clase que pueden variar dependiendo de las implementaciones del compilador, y por lo tanto pueden dar lugar inesperado InvalidClassExceptions durante la deserialización. Por lo tanto, para garantizar un valor consistente serialVersionUID en diferentes implementaciones del compilador Java, una clase serializable debe declarar un valor serialVersionUID explícito. También se recomienda encarecidamente que las declaraciones explícitas serialVersionUID usen el modificador private siempre que sea posible, ya que dichas declaraciones se aplican solo a la clase que declara inmediatamente: los campos serialVersionUID no son útiles como miembros heredados. Las clases de matriz no pueden declarar un serialVersionUID explícito, por lo que siempre tienen el valor calculado predeterminado, pero el requisito para hacer coincidir los valores de serialVersionUID no se aplica a las clases de matriz.

Debe definir un serialVersionUID en la definición de clase, por ejemplo .:

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

cómo ajustar el serialVersionUID en la definición? – lonesome

+0

aún ocurre el mismo error – lonesome

+0

Eso es extraño. Verificaría que ambas partes estén usando la versión más nueva de la clase. – trutheality

0

Creo que esto se debe a que utiliza las diferentes versiones de la misma clase en el cliente y el servidor. Puede tratarse de diferentes campos o métodos de datos

0

La serialización en java no está pensada para el formato de persistencia o transporte a largo plazo; es demasiado frágil para esto. Con la más mínima diferencia en bytecode de clase y JVM, sus datos ya no son legibles.Utilice el enlace de datos XML o JSON para su tarea (XStream es rápido y fácil de usar, y hay un montón de alternativas)

+2

Puedo aceptar un grado de persistencia, pero no hay nada de malo en utilizar la serialización de Java como formato de transporte. Es demasiado frágil si no se conocen los conceptos de serialización de Java como 'serialVersionUID''s. –

+0

Es frágil incluso entonces. –

+0

No lo es, realmente. Tal vez solo vemos el mundo de 'serialización de Java' con gafas de diferentes colores. Además, es prácticamente la única opción cuando se usa RMI. Además, veo que has hecho un comentario acerca de 'project manager skinning something' que fue editado más tarde ... –

0

El mensaje de excepción dice claramente que las versiones de clase, que incluirían los metadatos de clase también , ha cambiado con el tiempo En otras palabras, la estructura de clases durante la serialización no es la misma durante la deserialización. Esto es lo más probable "que esté pasando".

Cuestiones relacionadas