lo que podría modificar el serialVersionUID al serializar y almacenar en un archivo JAR?

StackOverflow https://stackoverflow.com/questions/1092255

Pregunta

Estoy frente a algunos problemas, mientras que la serialización de objetos (estoy usando JBoss Drools, y desea almacenar un ArrayList de KnowledgePackage).

Cuando serializar la lista, guardar el resultado en un archivo y deserializar ella, no se produce ningún problema, por lo que funciona bien.

Pero cuando serializar la lista, guardar el resultado en un flujo de bytes, a continuación, guardarlo en un JarFile, no puedo continuación, deserializar el resultado, debido a este error:

IOException during package import : java.util.ArrayList; local class incompatible: stream classdesc serialVersionUID = 8664875232659988799, local class serialVersionUID = 8683452581122892189

Así que creo que el problema es cuando estoy ahorrando el objeto serializado en una entrada JarFile. Creo que estoy haciendo bien, porque otros archivos guardan la misma manera en el JarFile correctamente puede ser leído. Y después de usar 'cmp' y 'hexdump', he descubierto que el ahorro es que es un frasco provoca una variación de un octeto si el UUID, de lo contrario el contenido es el mismo.

Estoy muy decepcionado y no puedo afirmar que el problema puede ser.

Lo que se puede modificar el serialVersionUID entre dos clases? que no sea otra versión vm?


añadir código fuente:  exportToJar -> writeRulesPackageEntry -> WriteEntry

/**
 * Writes content provided from a reader into a file contained in a jar.
 * 
 * @param output the output stream to write on
 * @param entryName the name of the file that will contain reader data
 * @param contentReader 
 * 
 * @return the zip entry that has been created into the jar
 */
ZipEntry writeEntry(JarOutputStream output, String entryName, ByteArrayInputStream input) {
    if (output == null || entryName == null || entryName.trim().length() == 0 || input == null) {
        throw new NullPointerException("Null argument passed");
    }

    ZipEntry entry = new ZipEntry(entryName);
    byte[] buffer = new byte[BUFFER_LENGTH];

    try {
        output.putNextEntry(entry);
        int nRead;

        while ((nRead = input.read(buffer, 0, BUFFER_LENGTH)) > 0) {
            output.write(buffer, 0, nRead);
        }

        output.closeEntry();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return entry;
}

/**
 * Export rules files to a serialized object (ArrayList<KnowledgePackage>) into 
 * an output stream, then write the output content as an entry of a jar.
 * 
 * @param os the output jar to write in
 */
void writeRulesPackageEntry(JarOutputStream os) {
    // serialize objects and write them to the output stream
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    RulesPackaging rulesPackaging = new RulesPackaging();
    rulesPackaging.exportResources(this.rules, output);

    // create a new input stream to read written objects from
    ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
    this.writeEntry(os, Product.ENTRY_RULES_PACKAGE, input);
}

/**
 * Creates a JarFile containing resources. 
 * 
 * @param filename the exported jar filename
 * @return the jar as an object, null if an error occured
 */
public JarFile exportToJar(String filename) {
    FileOutputStream fOs;
    JarOutputStream jOs;
    JarFile jar = null;

    try {
        fOs = new FileOutputStream(filename);
        jOs = new JarOutputStream(fOs);

        this.writeRulesPackageEntry(jOs);

        jOs.close();

        // construct a jar from the output jar
        jar = new JarFile(new File(filename));
    } catch (IOException e) {
        e.printStackTrace();
    }

    return jar;
}
¿Fue útil?

Solución

El serialVersionUID no cambia. Es un static final asignado en tiempo de compilación (basado en un hash del código fuente, creo) a menos que se asigna un valor de forma explícita en el código fuente.

Hay un poco más sobre ello aquí http://mindprod.com/jgloss/serialization.html .

Con la excepción que está viendo la serialVersionUID correcta para java.util.ArrayList es 8683452581122892189L, que se asigna de forma explícita en el código fuente y se ha mantenido igual desde la clase se introdujo en 1.2.

Como se ha dicho que el error es más probable que se produce cuando el flujo de bytes a JarFile -. Por favor enviar el código que está utilizando para hacer eso

Continúa después de que el código fuente se publicó

Sospecho que el problema radica en el uso de la java.io.InputStreamReader.

Desde el JavaDoc:

  

Una InputStreamReader es un puente de   byte arroyos a streams de caracteres: Se   Lee bytes y los decodifica en   caracteres utilizando un juego de caracteres especificado.   El juego de caracteres que se utiliza puede ser   especificado por el nombre o puede ser dado   explícitamente o por defecto de la plataforma   charset puede ser aceptado.

Tan pronto como veo los juegos de caracteres implicados en la no-Secuencias de texto que siempre consiguen sospechoso porque es posible que la corriente que va a modificarse durante la decodificación es una secuencia de bytes no corresponde a un personaje en el juego de caracteres (visto esos pequeños caracteres cuadrados que se produce cuando suceden problemas de codificación). Me gustaría tratar de leer los bytes directamente de la java.io.ByteArrayInputStream que está envolviendo a la java.io.InputStreamReader en writeRulesPackageEntry(JarOutputStream). La conversión a un char[] no es necesario.

Otros consejos

Al igual que Nick propone, el problema es más probable que usted no está tratando a la corriente como bytes (que nunca se alteran), sino como personajes (que puede ser).

Una vez dicho esto, otro recurso digno de serialización es un capítulo dedicado de un libro que escribí hace un millón de años (1997), "El dominio de JavaBeans". Por suerte el capítulo 11, la serialización, es hoy tan relevante como lo era entonces. Descargar los archivos PDF de forma gratuita http://ccd.uab.es/~srobles/manuals/JavaBeans

¿Hay alguna posibilidad de que una versión anterior fue publicado en el JarFile y posteriores intentos de serialización están fallando a reemplazarlo? Entonces sería la recuperación de los datos serializados de una versión anterior de la clase, lo que (correctamente) tirar el error "incompatibles".

La razón que pido, es que he visto mensajes de error similares usando mi sistema de almacenamiento en caché de elección (EHCache) cuando ya se ha actualizado una clase serializado aún no han bajado la edad caché persistente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top