solitario
Creé el cliente y el servidor y luego agregué una clase en el lado del cliente para fines de serialización, luego simplemente fui a la carpeta del cliente en mi disco duro y copié y pegué en la ubicación correspondiente del servidor, ambos classname.class
y classname.java
respectivamente.
Funcionó bien en mi propia computadora portátil, pero cuando quise continuar mi trabajo en otro sistema, cuando abrí las carpetas de proyectos y después de que el 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;
}
verdadrealidad
Si una clase no define explícitamente un private static final long serialVersionUID
en el código se generará automáticamente, y no hay garantía de que diferentes máquinas generen la misma identificación; parece que eso es exactamente lo que sucedió. Además, si las clases son diferentes de alguna manera (usando diferentes versiones de la clase), el autogenerado serialVersionUID
s también será diferente.
Desde el Serializable
interfaz documentos:
Si una clase serializable no declara explícitamente un
serialVersionUID
entonces el tiempo de ejecución de serialización calculará un valor predeterminadoserialVersionUID
valor para esa clase en función de varios aspectos de la clase, como se describe en la Especificación de serialización de objetos Java(TM). Sin embargo lo és muy recomendado que todas las clases serializables declaran explícitamenteserialVersionUID
valores, ya que el valor predeterminadoserialVersionUID
el cálculo es muy sensible a los detalles de la clase que pueden variar según las implementaciones del compilador y, por lo tanto, pueden generar resultados inesperados.InvalidClassExceptions
durante la deserialización. Por lo tanto, para garantizar una consistenciaserialVersionUID
valor a través de diferentes implementaciones del compilador Java, una clase serializable debe declarar un explícitoserialVersionUID
valor. También se recomienda encarecidamente que sea explícitoserialVersionUID
Las declaraciones utilizan elprivate
modificador cuando sea posible, ya que tales declaraciones se aplican solo a la clase que declara inmediatamente:serialVersionUID
los campos no son útiles como miembros heredados. Las clases de matriz no pueden declarar un explícitoserialVersionUID
por lo que siempre tienen el valor calculado predeterminado, pero el requisito de coincidenciaserialVersionUID
los valores se renuncia para las clases de matriz.
Debes definir un serialVersionUID
en la definición de clase, por ejemplo:
class MyClass implements Serializable {
private static final long serialVersionUID = 6529685098267757690L;
...
-
¿Cómo ajustar serialVersionUID en la definición?
– solitario
30 de abril de 2012 a las 5:36
-
Eso es extraño. Verificaría dos veces que ambos lados estén usando la versión más nueva de la clase.
– veracidad
30 de abril de 2012 a las 6:19
-
Incluso hice dos nuevos proyectos con el mismo nombre y creé las clases desde el principio, pero aún así sucede.
– solitario
30 de abril de 2012 a las 6:39
-
intente limpiar los resultados del proyecto (
.class
archivos generados en el momento de la compilación) y reconstruir (recompilar) los proyectos.– yair
30 de abril de 2012 a las 6:47
-
@EJP no es recomendable tratar de hacer coincidir el SUID con una versión diferente de la clase. Actualizar la clase en ambos extremos fue lo correcto aquí.
– veracidad
30 de abril de 2012 a las 18:48
Una cosa que pudo haber pasado:
- 1: crea sus datos serializados con una biblioteca A dada (versión X)
- 2: luego intenta leer estos datos con la misma biblioteca A (pero la versión Y)
Por tanto, en tiempo de compilación para la versión X, la JVM generará un primer Serial ID (para la versión X) y hará lo mismo con la otra versión Y (otro Serial ID).
Cuando su programa intenta deserializar los datos, no puede porque las dos clases no tienen el mismo ID de serie y su programa no tiene garantía de que los dos objetos serializados correspondan al mismo formato de clase.
Suponiendo que haya cambiado su constructor mientras tanto y esto debería tener sentido para usted.
Si está utilizando el IDE de Eclipse, verifique su configuración de depuración/ejecución. En la pestaña Classpath, seleccione el proyecto ejecutor y haga clic en el botón Editar.
Incluir solo entradas exportadas debe ser revisado.
Intente eliminar/cambiar el nombre del archivo de salida y vuelva a crear uno nuevo si almacenó un objeto durante la prueba. Tuve este error porque había serializado datos en el mismo archivo en dos clases de jFrame diferentes.
Creo que esto sucede porque usa las diferentes versiones de la misma clase en el cliente y el servidor. Pueden ser diferentes campos de datos o métodos.
nawazish-stackoverflow
El mensaje de excepción habla claramente de que las versiones de la clase, que también incluirían los metadatos de la clase, han 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 que probablemente “está pasando”.
jpaugh
La serialización en Java no está pensada como formato de transporte o persistencia a largo plazo; es demasiado frágil para esto. Con la más mínima diferencia en el código de bytes de clase y JVM, sus datos ya no se pueden leer. 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)
-
Puedo estar de acuerdo hasta cierto punto con la persistencia, pero no hay nada de malo en usar la serialización de Java como formato de transporte. Es demasiado frágil si uno no conoce los conceptos de serialización de Java como
serialVersionUID
‘s.– Sanjay T. Sharma
30 de abril de 2012 a las 6:43
-
No lo es, de verdad. Tal vez solo veamos el mundo de la ‘serialización de Java’ con lentes de diferentes colores. Además, es prácticamente la única opción cuando se usa RMI. Además, veo que hiciste un comentario sobre ‘jefe de proyecto desollando algo’ que se eliminó más tarde…
– Sanjay T. Sharma
30 de abril de 2012 a las 8:47
-
“La más mínima diferencia en el código de bytes de clase y JVM y sus datos ya no se pueden leer”. Esto es simplemente falso. Consulte la sección Control de versiones de objetos de la Especificación de serialización de objetos.
– usuario207421
30 de abril de 2012 a las 10:06
-
@EJP Aquí hay un enlace: Versionado de objetos serializables
– jpaugh
20 de septiembre de 2016 a las 14:12