JDK-6304463 : zip file IO operations on Solaris fail if thread is interrupted
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.jar
  • Affected Version: 6
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS:
    solaris,solaris_8,solaris_9,solaris_10 solaris,solaris_8,solaris_9,solaris_10
  • CPU: generic,sparc
  • Submitted: 2005-08-01
  • Updated: 2012-03-23
  • Resolved: 2005-08-20
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b49Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Description
The changes for
 6280693: Mmap the whole jar files takes too much perceived footprint
have caused failures on Solaris when an interrupted thread uses the java.util.zip API.

The following program:
---------------------------------------------------------------
import java.util.zip.*;

public class InterruptibleZip {
    private static String rtJar() {
	String bcp = System.getProperty("sun.boot.class.path");
	for (String jar : bcp.split("[;:]"))
	    if (jar.endsWith("rt.jar"))
		return jar;
	throw new Error("Can't find rt.jar");
    }

    public static void main(String[] args) throws Exception {
	ZipFile zf = new ZipFile(rtJar());
	Thread.currentThread().interrupt();
	ZipEntry ze = zf.getEntry("java/lang/Object.class");
	System.out.println("interrupted="+Thread.interrupted());
	System.out.println(ze.getName());
    }
}
---------------------------------------------------------------

results in 

...b45/binaries/solaris-sparc/jre/lib/rt.jar: error reading zip file
Exception in thread "main" java.lang.NoClassDefFoundError: java/util/zip/ZipEntry

Comments
EVALUATION To cope with interruptible I/O on Solaris, we should avoid calling JVM_Read, instead we could call "read" directly. That will solve the issue of getting JVM_IO_INTR from JVM_Read call and processing it. Since continuing calling JVM_Read requires clear the interrupt status which could have some trivial side effect.
02-08-2005

EVALUATION Here's a more complete and careful regression test. If this works, we've probably fixed the regression. ----------------------------------------------- import java.io.*; import java.util.zip.*; public class InterruptibleZip { private static String rtJar() { String bcp = System.getProperty("sun.boot.class.path"); for (String jar : bcp.split("[;:]")) if (jar.endsWith("rt.jar")) return jar; throw new Error("Can't find rt.jar"); } public static void main(String[] args) throws Exception { Thread.currentThread().interrupt(); ZipFile zf = new ZipFile(rtJar()); ZipEntry ze = zf.getEntry("java/lang/Object.class"); InputStream is = zf.getInputStream(ze); byte[] buf = new byte[512]; int n = is.read(buf); boolean interrupted = Thread.interrupted(); System.out.printf("interrupted=%s n=%d name=%s%n", interrupted, n, ze.getName()); if (! interrupted) throw new Error("! interrupted"); if (n != buf.length) throw new Error("read"); } }
01-08-2005

SUGGESTED FIX One way to do this is to handle this is to deal with JVM_IO_INTR and retry. Code must be written very carefully. Code sketch: static int Read_Uninterruptibly(...) { int interrupted = 0; n = JVM_Read(...); if (n == JVM_IO_INTR) { JVM_isInterrupted(...,...,0); n = Read_Uninterruptibly(...); JVM_Interrupt(...); } return n; }
01-08-2005

EVALUATION mmap operations aren't affected by the interrupt status, but JVM_Read and friends are, and we're using those operations on Solaris after mustang b45. Interruptible IO is a difficult subject.
01-08-2005