1 /*
2  * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /**
25  * @test
26  * @bug 6423026
27  * @summary Check that it is possible to open more than 2,048 zip files on
28  * Windows.
29  */
30 
31 import java.util.zip.ZipEntry;
32 import java.util.zip.ZipFile;
33 import java.util.zip.ZipOutputStream;
34 import java.io.ByteArrayOutputStream;
35 import java.io.File;
36 import java.io.FileOutputStream;
37 
38 public class ManyZipFiles {
39     static final int numFiles = 3000;
40 
realMain(String[] args)41     public static void realMain(String[] args) throws Throwable {
42         // Linux does not yet allow opening this many files; Solaris
43         // 8 requires an explicit allocation of more file descriptors
44         // to succeed. Since this test is written to check for a
45         // Windows capability it is much simpler to only run it
46         // on that platform.
47         String osName = System.getProperty("os.name");
48         if (!(osName.startsWith("Windows"))) {
49             return;
50         }
51 
52         // Create some zip data
53         ByteArrayOutputStream baos = new ByteArrayOutputStream();
54         try (ZipOutputStream zos = new ZipOutputStream(baos)) {
55             ZipEntry ze = new ZipEntry("test");
56             zos.putNextEntry(ze);
57             byte[] hello = "hello, world".getBytes("ASCII");
58             zos.write(hello, 0, hello.length);
59             zos.closeEntry();
60             zos.finish();
61         }
62         byte[] data = baos.toByteArray();
63 
64         ZipFile zips[] = new ZipFile[numFiles];
65 
66         try {
67             // Create a directory for zip files created below
68             File tmpdir = new File(
69                 System.getProperty("java.io.tmpdir")
70                 + File.separator + "ManyZipFiles");
71             if (tmpdir.exists() && !tmpdir.isDirectory()) {
72                 fail(tmpdir.getAbsolutePath()
73                      + " already exists but is not a directory");
74                 return;
75             }
76             if (!tmpdir.exists()) {
77                 if (!tmpdir.mkdirs()) {
78                     fail("Couldn't create directory "
79                          + tmpdir.getAbsolutePath() + " for test files");
80                     return;
81                 }
82             } else if (!tmpdir.canWrite()) {
83                 fail("Don't have write access for directory "
84                      + tmpdir.getAbsolutePath() + " for test files");
85                 return;
86             }
87             tmpdir.deleteOnExit();
88 
89             // Create and then open a large number of zip files
90             for (int i = 0; i < numFiles; i++) {
91                 File f = File.createTempFile("test", ".zip", tmpdir);
92                 f.deleteOnExit();
93                 try (FileOutputStream fos = new FileOutputStream(f)) {
94                     fos.write(data, 0, data.length);
95                 }
96                 try {
97                     zips[i] = new ZipFile(f);
98                 } catch (Throwable t) {
99                     fail("Failed to open zip file #" + i + " named "
100                          + zips[i].getName());
101                     throw t;
102                 }
103             }
104         } finally {
105             // This finally block is due to bug 4171239.  On Windows, if the
106             // file is still open at the end of the VM, deleteOnExit won't
107             // take place.  "new ZipFile(...)" opens the zip file, so we have
108             // to explicitly close those opened above.  This finally block can
109             // be removed when 4171239 is fixed. See also 6357433, against which
110             // 4171239 was closed as a duplicate.
111             for (int i = 0; i < numFiles; i++) {
112                 if (zips[i] != null) {
113                     try {
114                         zips[i].close();
115                     } catch (Throwable t) {
116                         fail("At zip[" + i + "] named " + zips[i].getName()
117                              + " caught " + t);
118                     }
119                 }
120             }
121         }
122         pass();
123     }
124 
125     //--------------------- Infrastructure ---------------------------
126     static volatile int passed = 0, failed = 0;
pass()127     static void pass() {passed++;}
fail()128     static void fail() {failed++; Thread.dumpStack();}
fail(String msg)129     static void fail(String msg) {System.out.println(msg); fail();}
unexpected(Throwable t)130     static void unexpected(Throwable t) {failed++; t.printStackTrace();}
check(boolean cond)131     static void check(boolean cond) {if (cond) pass(); else fail();}
equal(Object x, Object y)132     static void equal(Object x, Object y) {
133         if (x == null ? y == null : x.equals(y)) pass();
134         else fail(x + " not equal to " + y);}
main(String[] args)135     public static void main(String[] args) throws Throwable {
136         try {realMain(args);} catch (Throwable t) {unexpected(t);}
137         System.out.println("\nPassed = " + passed + " failed = " + failed);
138         if (failed > 0) throw new AssertionError("Some tests failed");}
139 }
140