JDK-4607439 : No way how to recover after InternalError jzentry == null
  • Type: Bug
  • Component: tools
  • Sub-Component: jar
  • Affected Version: 1.4.0
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2001-12-13
  • Updated: 2001-12-14
  • Resolved: 2001-12-14
Related Reports
Duplicate :  
Description

Name: gm110360			Date: 12/13/2001


java version "1.4.0-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.
Java HotSpot(TM) Client VM (build 1.4.0-rc-b85, mixed mode)

Problem is that in my code I`m not able to recover from previous problem ():
java.lang.InternalError: jzentry == 0,
 jzfile = 296227752,
 total = 36,
 name = C:\Development\Test5.jar,
 i = 2,
 message = couldn't read LOC header
        at java.util.zip.ZipFile$2.nextElement(ZipFile.java:306)
        at java.util.jar.JarFile$1.nextElement(JarFile.java:203)

This exception is fired from thread that enumerates ZipEntries while another
thread modifies content of the same jar (e.g.: using JarOutputStream). Problem
is that I`m not able to recover from this problem, after modification is
complete. I would expect that if I used following fragment of code, JarFile
should be usefull again:
                jf.close();
                jf = new JarFile(file);
                en = jf.entries();
                .....

Please evaluate this program that demonstrates this problem:

import java.io.*;
import java.util.*;
import java.util.jar.*;
import java.util.zip.*;
/**
 *
 * @author  Radek Matous
 * @version
 */
public class BugVerif {

    /** Creates new FromFile */
    public BugVerif() {
    }

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) throws Exception{
        /** I wrote program that demonstrate this bug.
         * There is only one thread to simplify problem.
         * But we can imagine that any thread holds instance
         * of JarFile (see jfOpen). One thread is enumerating
         * entries when another thread modifies JarFile (see errorCause).
         * Then enumerating thread is broken and exception is
         * caught and this thread tries to recover
         * of this problem. But there is no reasonable way how to do it.
         */
        File file = new File("C:\\Development\\Test5.jar");
        /** Comment/uncomment next line. If you comment next line with
         * jfOpen, then program will finish right.*/
        JarFile jfOpen  = new JarFile(file);
        JarFile jf = new JarFile(file);
        Enumeration en = jf.entries();
        
        boolean  error = false;
        int i = 0;
        
        /** To prevent from infinite loop.*/
        for (i = 0; i < 10; i++) {
            try {
                while ( en.hasMoreElements()) {
                    Object obj = en.nextElement();
                    /** Cause of error.*/
                    if (!error) {
                        error = !error;
                        errorCause (file, obj.toString());
                    }
                }
                /** Never reached */
                jf.close();
                break;
            } catch (Throwable t) {
                t.printStackTrace();
                /** Recovering*/
                Thread.sleep(1000);
                jf.close();
                jf = new JarFile(file);
                en = jf.entries();
            }
        }
        /** Result: */
        if (i < 20)
            System.out.println("RESULT: no error");
        else
            System.out.println("RESULT: error proved");
    }
    
    public static void errorCause (File file, String name) throws IOException{
        JarOutputStream jos = new JarOutputStream  (new FileOutputStream(file));
        ZipEntry z;
        jos.putNextEntry(z = new ZipEntry (name+"_X"));
        jos.close();
    }
}
(Review ID: 136282) 
======================================================================
Priority increased to P3 which I consider more appropriate then P4 (see justification).

Comments
EVALUATION This is a duplicate of 4353705, fixed in Merlin fcs.
11-06-2004