Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4607439

No way how to recover after InternalError jzentry == null

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P3 P3
    • None
    • 1.4.0
    • tools
    • jar
    • x86
    • windows_2000



      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).

            kkladkosunw Konstantin Kladko (Inactive)
            gmanwanisunw Girish Manwani (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: