Summary: | unzip task input file remains open after exception | ||
---|---|---|---|
Product: | Ant | Reporter: | gjfdh |
Component: | Core tasks | Assignee: | Ant Notifications List <notifications> |
Status: | RESOLVED FIXED | ||
Severity: | critical | CC: | notifications |
Priority: | P2 | ||
Version: | 1.6.3 | ||
Target Milestone: | 1.6.4 | ||
Hardware: | All | ||
OS: | Windows Server 2003 |
Description
gjfdh
2005-05-12 15:21:36 UTC
I don't see how unzip would not close the file since it is inside a finally block. Except for File.close() failing, but then we'd be out of luck anyway. Could it be a timing issue? One where Java has close the stream but your OS hasn't recognized this? Does it help if you put a short <sleep> in front of the delete? Sleep doesn't help. Some automated code I have has looped on this bug, repeatedly trying to delete the file, over an entire weekend with no luck. And, if it was a timing issue, in OS code, this same bug would have shown when deleting properly formatted zip files. Assuming everything else is the same, the OS wouldn't care if the zip was formatted properly or not -- a close is a close. The test build.xml file I gave above works under unix systems [touch] Creating /tmp/xxx.zip [unzip] Expanding: /tmp/xxx.zip into /tmp [subant] Exiting /tmp/build.xml. [subant] Failure for target 'do-unzip' of: /tmp/build.xml [subant] The following error occurred while executing this line: [subant] /tmp/build.xml:4: Error while expanding /tmp/xxx.zip [delete] Deleting: /tmp/xxx.zip by the delete semantics are different there. You are allowed to delete open files hence this test doesn't show if the bug exists or not on unix -- the symptom is gone but the bug may or may not be there. It is tricky. I'm hoping that someone in the bugzilla audience may know something about zipfile or Windows or ... which can explain what's going on. I think it's a matter of finalizers. Expand.java creates a ZipFile. An IOException is thrown during the ZipFile constructor when archive.seek() is called with a negative offset in the positionAtCentralDirectory method. The instance variable, archive, is holding a RandomAccessFile object and eventually may be garbage collected. But until then, the file remains open. The zf.close() in Expand.java's finally is irrelevant here because the exception happened during the "zf = new ZipFile..." statement. The fix is to change the ZipFile so it explicitly closes "archive". New constructor: public ZipFile(File f, String encoding) throws IOException { this.encoding = encoding; archive = new RandomAccessFile(f, "r"); try { populateFromCentralDirectory(); resolveLocalFileHeaderData(); } catch (IOException e) { archive.close(); throw e; } } Old constructor (for comparision purposes): public ZipFile(File f, String encoding) throws IOException { this.encoding = encoding; archive = new RandomAccessFile(f, "r"); populateFromCentralDirectory(); resolveLocalFileHeaderData(); } Here's some standalone test code which also exhibits the problem: import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; public class Test { public static void main( String[] args ) { final String fileName = "xxx.zip"; //WORKS RandomAccessFile f2 = null; try { // Touch the file new RandomAccessFile(fileName, "rw").close(); // Perform a seek. This throws an IOException RandomAccessFile f2 = null; f2 = new RandomAccessFile(fileName, "r"); f2.seek(-2); } catch (IOException e) { e.printStackTrace(); /* WORKS try { System.out.println("Explictly closing the file"); f2.close(); } catch (IOException e2) { e2.printStackTrace(); } WORKS */ } final boolean rc = new File(fileName).delete(); System.out.println(rc); } Leave the comments in the code, and the delete() method returns false. Uncomment the WORKS lines (and move the var declaration up) and the delete() method returns true. I could have been staring at the code for ages without realizing that the constructor was throwing the exception. Thanks! A stack-trace would have been helpful. The same problem could happen in <untar> as well, <gunzip> and <bunzip2> seem to be save. Fixed in CVS, should be fixed in 1.6.4. If you can build Ant from sources or pick up a nightly build of 2005-05-14 or later to confirm it has been fixed, that would be great. |