JDK-4843994 : JarURLConnection gets confused and throws exceptions after replacing jar file
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.jar
  • Affected Version: 1.3.1_09,1.4.1_01
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic,windows_2000
  • CPU: generic,x86
  • Submitted: 2003-04-07
  • Updated: 2003-04-11
  • Resolved: 2003-04-11
Related Reports
Duplicate :  
Description
JDK 1.4.1, Windows 2000.

When JarURLConnection uses setUseCaches(true) - which is the default - and the jar file it reads changes underneath, then JarURLConnection will get confused and is unable to read the zip file.

See also http://www.netbeans.org/issues/show_bug.cgi?id=31573 for more information.

To reproduce:
1. Create JarURLConnection that caches the jar/zip file
2. Read all entries of the jar/zip file in a loop
3. Programatically replace the jar/zip file by another one (from the same VM)
4. Read all entries again

The following exception will be thrown:
java.lang.InternalError: jzentry == 0,
 jzfile = 258096688,
 total = 8,
 name = c:\jdkbug\test.zip,
 i = 2,
 message = invalid LOC header (bad signature)
        at java.util.zip.ZipFile$2.nextElement(ZipFile.java:309)
        at java.util.jar.JarFile$1.nextElement(JarFile.java:201)
        at JarURLConnectionBug.readJar(JarURLConnectionBug.java:51)
        at JarURLConnectionBug.main(JarURLConnectionBug.java:32)

I am attaching a zip file containing the following:
- a small test which reproduces the problem
- zip archives as test data
- output of the test which shows the exception 


Note: I just checked on JDK 1.4.2 beta and the bug still occurs, although with a different message:

An unexpected exception has been detected in native code outside the VM.
Unexpected Signal : EXCEPTION_ACCESS_VIOLATION (0xc0000005) occurred at PC=0x77FCA200
Function=RtlDestroyHeap+0x311
Library=C:\WINNT\System32\ntdll.dll

Current Java thread:
        at java.util.zip.ZipFile.getNextEntry(Native Method)
        at java.util.zip.ZipFile.access$400(ZipFile.java:26)
        at java.util.zip.ZipFile$2.nextElement(ZipFile.java:313)
        - locked <0x10032118> (a sun.net.www.protocol.jar.URLJarFile)
        at java.util.jar.JarFile$1.nextElement(JarFile.java:211)
        at JarURLConnectionBug.readJar(JarURLConnectionBug.java:51)
        at JarURLConnectionBug.main(JarURLConnectionBug.java:32)

Dynamic libraries:
0x00400000 - 0x00406000         c:\j2sdk1.4.2\bin\java.exe
0x77F80000 - 0x77FF9000         C:\WINNT\System32\ntdll.dll
0x77DB0000 - 0x77E0A000         C:\WINNT\system32\ADVAPI32.dll
0x77E80000 - 0x77F36000         C:\WINNT\system32\KERNEL32.DLL
0x77D40000 - 0x77DAF000         C:\WINNT\system32\RPCRT4.DLL
0x78000000 - 0x78046000         C:\WINNT\system32\MSVCRT.dll
0x08000000 - 0x08136000         c:\j2sdk1.4.2\jre\bin\client\jvm.dll
0x77E10000 - 0x77E75000         C:\WINNT\system32\USER32.dll
0x77F40000 - 0x77F7C000         C:\WINNT\system32\GDI32.DLL
0x77570000 - 0x775A0000         C:\WINNT\System32\WINMM.dll
0x10000000 - 0x10007000         c:\j2sdk1.4.2\jre\bin\hpi.dll
0x007C0000 - 0x007CE000         c:\j2sdk1.4.2\jre\bin\verify.dll
0x007D0000 - 0x007E8000         c:\j2sdk1.4.2\jre\bin\java.dll
0x007F0000 - 0x007FD000         c:\j2sdk1.4.2\jre\bin\zip.dll
0x77920000 - 0x77942000         C:\WINNT\system32\imagehlp.dll
0x72A00000 - 0x72A2D000         C:\WINNT\system32\DBGHELP.dll
0x690A0000 - 0x690AB000         C:\WINNT\System32\PSAPI.DLL

Heap at VM Abort:
Heap
 def new generation   total 576K, used 153K [0x10010000, 0x100b0000, 0x104f0000)
  eden space 512K,  29% used [0x10010000, 0x10036638, 0x10090000)
  from space 64K,   0% used [0x10090000, 0x10090000, 0x100a0000)
  to   space 64K,   0% used [0x100a0000, 0x100a0000, 0x100b0000)
 tenured generation   total 1408K, used 0K [0x104f0000, 0x10650000, 0x14010000)
   the space 1408K,   0% used [0x104f0000, 0x104f0000, 0x104f0200, 0x10650000)
 compacting perm gen  total 4096K, used 1030K [0x14010000, 0x14410000, 0x18010000)
   the space 4096K,  25% used [0x14010000, 0x14111930, 0x14111a00, 0x14410000)

Local Time = Mon Apr 07 20:13:23 2003
Elapsed Time = 1
#
# The exception above was detected in native code outside the VM
#
# Java VM: Java HotSpot(TM) Client VM (1.4.2-beta-b19 mixed mode)
#
# An error report file has been saved as hs_err_pid4628.log.
# Please refer to the file for further information.
#
 

There is one more thing I forgot: to use the attached test case, you need to modify the path to the jar file on lines 25-28.

Also, there is another strange thing about JarURLConnection: When you get the JarFile from the connection, and then close() it, and then obtain the JarURLConnection again, there does not seem to be a way to read from the jar again, as it complains that it is closed. This is when you use the caching mode.

###@###.### 2003-04-07

Comments
WORK AROUND Workaround is to set jarurlconnection.setUseCaches(false). However, this did not work in 1.3.0, so a lot of existing code does not do that (even if it would be appropriate). ###@###.### 2003-04-07 Actually, it seems that the workaround is not reliable with 1.4.2. It works on some Windows OS versions, but not others. It also seems to depend on the filesystem type. ###@###.### 2003-04-14
14-04-2003

EVALUATION waiting for a test case. ###@###.### 2003-04-07 The problem seems to be that while some of the info is cached, the actual entries will still be read from the jar file. in case of this particular test, since the jar file is changed after it's cashed, there will be a mismatch between what is cached and what are the actual entries are. Thus the error. I think this is a corner case that needs further evaluation in Tiger. ###@###.### 2003-04-07 Well, I am not quite sure this is a corner case. Searching Google for "jzentry == 0" reveals that people have had this problem in the past; it probably has not been reported because it is hard to reproduce reliably. Also, this problem may affect typical J2EE servers, since there you redeploy apps by replacing the application jar files. For example, Tomcat uses setUseCaches(true), so it may be affected. If the patch is easy and straightforward, I would appreciate if this could be fixed for JDK 1.4.2. Thanks. ###@###.### 2003-04-10 We realized that JDK 1.4.2 beta has actually regressed against 1.4.1. While on 1.4.1 an exception is thrown, on 1.4.2 beta the VM crashes! Thus raising the priority to P2. ###@###.### 2003-04-11 We do not guarantee any behaviour if the jar file has been changed since the meta info has been cached. It was never the intent that such a scenario would ever be supported. This is a known issue that has been rarely diagnosed. Generally speaking, a friendly error message would be preferred over the current VM crash. However, the failure mode is highly dependent on exactly how the jar file has changed. A arbitrary stack trace, VM crash, or failure during later use of the jar file are all possible behaviours. In the past we have investigated the possibility of trying to do earlier detection of jar file modification without much success. On older file systems, the timestamp is guaranteed accurate only to the second. This granularity is far too large to properly detect potential modification of the underlying jar file. Even if the granularity was reduced, the necessary file operations would be a huge impact on the performance of jar file access. We expect a real fix to be exceedingly difficult. It may be impossible to fix this problem efficiently. We will re-investigate possible solutions in the Tiger timeframe. Until that time, we strongly suggest that applications not modify the jar file after its meta info has been cached. -- iag@sfbay 2003-04-11 Duplicate of 4425695. Modifying a jar file on the fly is not supported any more than changing a shared library or a class file on the fly. The only reason way to replace a jar file is to guarantee that the classloader (and all of its loaded classes and all objects of those) are no longer in use and suitable for garbage collection. ###@###.### 2003-04-11
11-04-2003