직렬화 및 저장을하면서 Serialversionuid를 수정할 수있는 것은 무엇입니까?

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

문제

객체를 직렬화하는 동안 몇 가지 문제에 직면하고 있습니다 (Jboss Drools를 사용하고 있으며 Knowledgepackage의 배열 목록을 저장하고 싶습니다).

목록을 직렬화하고 결과를 파일에 저장하고이를 실시 할 때 문제가 발생하지 않으므로 잘 작동합니다.

그러나 목록을 직렬화하고 결과를 바이트 스트림에 저장 한 다음 jarfile에 저장하면이 오류로 인해 결과를 사로화 할 수 없습니다.

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

따라서 문제는 직렬화 된 객체를 Jarfile 항목에 저장할 때라고 생각합니다. 다른 파일이 jarfile에서 같은 방식으로 저장 되었기 때문에이 문제를 제대로하고 있다고 생각합니다. 그리고 'CMP'와 'hexdump'를 사용한 후, 저장하면 항아리를 저장하면 uUID가 있으면 한 덩어리가 변형됩니다. 그렇지 않으면 내용이 동일합니다.

나는 정말로 실망하고 문제가 어디에 있는지 언급 할 수 없습니다.

두 클래스 사이에서 SerialversionUid를 수정할 수있는 것은 무엇입니까? 다른 VM 버전 외에?


소스 코드 추가 : 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;
}
도움이 되었습니까?

해결책

그만큼 serialVersionUID 변경되지 않습니다. 이것은 static final 소스 코드에 값이 명시 적으로 할당되지 않는 한 컴파일 타임 (소스 코드의 해시를 기준으로)에 할당되었습니다.

여기에 조금 더 있습니다 http://mindprod.com/jgloss/serialization.html.

예외적으로 당신은 올바른 것을보고 있습니다 serialVersionUID java.util.arraylist의 경우 8683452581122892189L은 소스 코드에 명시 적으로 할당되며 클래스가 1.2에 도입 된 이후로 동일하게 유지되었습니다.

당신이 말했듯이, 바이트가 jarfile로 스트리밍 할 때 오류가 발생할 가능성이 높습니다.

소스 코드가 게시 된 후 계속됩니다

나는 문제가 java.io.InputStreamReader.

Javadoc에서 :

InputStreamReader는 바이트 스트림에서 문자 스트림까지의 브리지입니다. 바이트를 읽고 지정된 숯을 사용하여 문자로 디코딩합니다. 사용하는 숯은 이름으로 지정 될 수 있거나 명시 적으로 주어 지거나 플랫폼의 기본 숯이 수락 될 수 있습니다.

텍스트가 아닌 스트림에 관련된 캐릭터 세트가 보자 마자 디코딩 중에 스트림이 수정 될 수 있기 때문에 항상 의심스러워집니다. 바이트 시퀀스는 문자 세트의 문자에 해당하지 않습니다 (작은 정사각형을 보았습니다. 인코딩 문제가 발생할 때 발생하는 문자). 바이트를 바로 읽으려고 노력할 것입니다 java.io.ByteArrayInputStream 당신이 java.io.InputStreamReader 안에 writeRulesPackageEntry(JarOutputStream). a로의 변환 char[] 필요하지 않습니다.

다른 팁

Nick이 제안한 것처럼, 문제는 스트림을 바이트 (절대 변경되지 않음)로 취급하는 것이 아니라 문자 (가능)로 취급 할 가능성이 높습니다.

그러나 직렬화에 대한 또 다른 괜찮은 자원은 백만 년 전에 쓴 책 (1997), "마스터 링 자비 베인"의 전용 장입니다. 운 좋게도 11 장, 직렬화는 오늘날만큼 관련이 있습니다. 무료 PDF를 다운로드하십시오 http://ccd.uab.es/~srobles/manuals/javabeans

이전 버전이 Jarfile에 직렬화되었을 가능성이 있습니까? 후속 직렬화 시도가이를 덮어 쓰지 못하고 있습니까? 그런 다음 이전 버전의 클래스의 직렬화 된 데이터를 검색 할 수 있습니다.이 클래스의 클래스는 "비 호환"오류를 올바르게 던질 수 있습니다.

내가 묻는 이유는 직렬화 된 클래스를 업데이트했지만 이전의 영구 캐시를 삭제하지 않았을 때 Caching System (EHCache)을 사용하여 유사한 오류 메시지를 보았 기 때문입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top