test/jdk/jdk/nio/zipfs/ZipFSTester.java

Print this page


   1 /*
   2  * Copyright (c) 2010, 2015, 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 import java.io.File;
  25 import java.io.IOException;
  26 import java.io.InputStream;
  27 import java.io.OutputStream;
  28 import java.net.URI;
  29 import java.net.URLDecoder;
  30 import java.nio.ByteBuffer;

  31 import java.nio.channels.FileChannel;
  32 import java.nio.channels.SeekableByteChannel;
  33 import java.nio.file.DirectoryStream;
  34 import java.nio.file.FileAlreadyExistsException;
  35 import java.nio.file.FileSystem;
  36 import java.nio.file.FileSystemAlreadyExistsException;
  37 import java.nio.file.FileSystemException;
  38 import java.nio.file.FileSystems;
  39 import java.nio.file.FileVisitResult;
  40 import java.nio.file.Files;
  41 import java.nio.file.OpenOption;
  42 import java.nio.file.Path;
  43 import java.nio.file.Paths;
  44 import java.nio.file.SimpleFileVisitor;
  45 import java.nio.file.attribute.BasicFileAttributeView;
  46 import java.nio.file.attribute.BasicFileAttributes;
  47 import java.nio.file.spi.FileSystemProvider;
  48 import java.util.ArrayList;
  49 import java.util.Arrays;
  50 import java.util.Collections;
  51 import java.util.Enumeration;
  52 import java.util.HashMap;
  53 import java.util.HashSet;
  54 import java.util.Iterator;
  55 import java.util.LinkedList;
  56 import java.util.List;
  57 import java.util.Map;
  58 import java.util.Random;
  59 import java.util.Set;
  60 import java.util.concurrent.TimeUnit;

  61 import java.util.zip.ZipEntry;
  62 import java.util.zip.ZipFile;

  63 
  64 import static java.nio.file.StandardOpenOption.*;
  65 import static java.nio.file.StandardCopyOption.*;
  66 
  67 /*
  68  * Tests various zipfs operations.
  69  *
  70  * @test
  71  * @bug 6990846 7009092 7009085 7015391 7014948 7005986 7017840 7007596
  72  *      7157656 8002390 7012868 7012856 8015728 8038500 8040059 8069211
  73  *      8131067
  74  * @summary Test Zip filesystem provider
  75  * @modules jdk.zipfs
  76  * @run main ZipFSTester
  77  * @run main/othervm/java.security.policy=test.policy ZipFSTester
  78  */
  79 
  80 public class ZipFSTester {
  81 
  82     public static void main(String[] args) throws Exception {
  83 
  84         // create JAR file for test, actual contents don't matter
  85         Path jarFile = Utils.createJarFile("tester.jar",
  86                 "META-INF/MANIFEST.MF",
  87                 "dir1/foo",
  88                 "dir2/bar");

  89 
  90         try (FileSystem fs = newZipFileSystem(jarFile, Collections.emptyMap())) {
  91             test0(fs);
  92             test1(fs);
  93             test2(fs);   // more tests
  94         }


  95         testTime(jarFile);
  96         test8069211();
  97         test8131067();
  98     }
  99 


 100     static void test0(FileSystem fs)
 101         throws Exception
 102     {
 103         List<String> list = new LinkedList<>();
 104         try (ZipFile zf = new ZipFile(fs.toString())) {
 105             Enumeration<? extends ZipEntry> zes = zf.entries();
 106             while (zes.hasMoreElements()) {
 107                 list.add(zes.nextElement().getName());
 108             }
 109             for (String pname : list) {
 110                 Path path = fs.getPath(pname);
 111                 if (!Files.exists(path))
 112                     throw new RuntimeException("path existence check failed!");
 113                 while ((path = path.getParent()) != null) {
 114                     if (!Files.exists(path))
 115                         throw new RuntimeException("parent existence check failed!");
 116                 }
 117             }
 118         }
 119     }
 120 
 121     static void test1(FileSystem fs0)
 122         throws Exception
 123     {
 124         Random rdm = new Random();
 125         // clone a fs and test on it








 126         Path tmpfsPath = getTempPath();
 127         Map<String, Object> env = new HashMap<String, Object>();
 128         env.put("create", "true");
 129         try (FileSystem copy = newZipFileSystem(tmpfsPath, env)) {
 130             z2zcopy(fs0, copy, "/", 0);







 131         }
 132 
 133         try (FileSystem fs = newZipFileSystem(tmpfsPath, new HashMap<String, Object>())) {
 134 
 135             FileSystemProvider provider = fs.provider();
 136             // newFileSystem(path...) should not throw exception
 137             try (FileSystem fsPath = provider.newFileSystem(tmpfsPath, new HashMap<String, Object>())){}
 138             try (FileSystem fsUri = provider.newFileSystem(
 139                      new URI("jar", tmpfsPath.toUri().toString(), null),
 140                      new HashMap<String, Object>()))
 141             {
 142                 throw new RuntimeException("newFileSystem(URI...) does not throw exception");
 143             } catch (FileSystemAlreadyExistsException fsaee) {}
 144 
 145             // prepare a src
 146             Path src = getTempPath();
 147             String tmpName = src.toString();
 148             OutputStream os = Files.newOutputStream(src);
 149             byte[] bits = new byte[12345];
 150             rdm.nextBytes(bits);
 151             os.write(bits);
 152             os.close();
 153 
 154             try {
 155                 provider.newFileSystem(new File(System.getProperty("test.src", ".")).toPath(),
 156                                        new HashMap<String, Object>());
 157                 throw new RuntimeException("newFileSystem() opens a directory as zipfs");
 158             } catch (UnsupportedOperationException uoe) {}
 159 
 160             try {
 161                 provider.newFileSystem(src, new HashMap<String, Object>());
 162                 throw new RuntimeException("newFileSystem() opens a non-zip file as zipfs");
 163             } catch (UnsupportedOperationException uoe) {}
 164 


 165 
 166             // copyin
 167             Path dst = getPathWithParents(fs, tmpName);
 168             Files.copy(src, dst);
 169             checkEqual(src, dst);
 170 
 171             // copy
 172             Path dst2 = getPathWithParents(fs, "/xyz" + rdm.nextInt(100) +
 173                                            "/efg" + rdm.nextInt(100) + "/foo.class");
 174             Files.copy(dst, dst2);
 175             //dst.moveTo(dst2);
 176             checkEqual(src, dst2);
 177 
 178             // delete
 179             Files.delete(dst);
 180             if (Files.exists(dst))
 181                 throw new RuntimeException("Failed!");
 182 
 183             // moveout
 184             Path dst3 = Paths.get(tmpName + "_Tmp");


 219             }
 220 
 221             // rmdirs
 222             try {
 223                 rmdirs(parent);
 224             } catch (IOException x) {
 225                 x.printStackTrace();
 226             }
 227 
 228             // newFileChannel() copy in, out and verify via fch
 229             fchCopy(src, dst);    // in
 230             checkEqual(src, dst);
 231             Path tmp = Paths.get(tmpName + "_Tmp");
 232             fchCopy(dst, tmp);   //  out
 233             checkEqual(src, tmp);
 234             Files.delete(tmp);
 235 
 236             // test channels
 237             channel(fs, dst);
 238             Files.delete(dst);
 239             Files.delete(src);



















 240         } finally {
 241             if (Files.exists(tmpfsPath))
 242                 Files.delete(tmpfsPath);
 243         }
 244     }
 245 
 246     static void test2(FileSystem fs) throws Exception {
 247 
 248         Path fs1Path = getTempPath();
 249         Path fs2Path = getTempPath();
 250         Path fs3Path = getTempPath();
 251 
 252         // create a new filesystem, copy everything from fs
 253         Map<String, Object> env = new HashMap<String, Object>();
 254         env.put("create", "true");
 255         FileSystem fs0 = newZipFileSystem(fs1Path, env);
 256 
 257         final FileSystem fs2 = newZipFileSystem(fs2Path, env);
 258         final FileSystem fs3 = newZipFileSystem(fs3Path, env);
 259 
 260         System.out.println("copy src: fs -> fs0...");
 261         z2zcopy(fs, fs0, "/", 0);   // copy fs -> fs1
 262         fs0.close();                // dump to file


 366 
 367         ArrayList<String> files2 = new ArrayList<>();
 368         ArrayList<String> dirs2 = new ArrayList<>();
 369         list(fs4.getPath("/"), files2, dirs2);
 370 
 371         System.out.println("checkEqual: fs vs fs4");
 372         for (String path : files2) {
 373             checkEqual(fs.getPath(path), fs4.getPath(path));
 374         }
 375         System.out.println("walking: fs4");
 376         walk(fs4.getPath("/"));
 377         System.out.println("closing: fs4");
 378         fs4.close();
 379         System.out.printf("failed=%d%n", failed);
 380 
 381         Files.delete(fs1Path);
 382         Files.delete(fs2Path);
 383         Files.delete(fs3Path);
 384     }
 385 
























































































































































 386     // test file stamp
 387     static void testTime(Path src) throws Exception {
 388         BasicFileAttributes attrs = Files
 389                         .getFileAttributeView(src, BasicFileAttributeView.class)
 390                         .readAttributes();
 391         // create a new filesystem, copy this file into it
 392         Map<String, Object> env = new HashMap<String, Object>();
 393         env.put("create", "true");
 394         Path fsPath = getTempPath();
 395         FileSystem fs = newZipFileSystem(fsPath, env);
 396 
 397         System.out.println("test copy with timestamps...");
 398         // copyin
 399         Path dst = getPathWithParents(fs, "me");
 400         Files.copy(src, dst, COPY_ATTRIBUTES);
 401         checkEqual(src, dst);
 402         System.out.println("mtime: " + attrs.lastModifiedTime());
 403         System.out.println("ctime: " + attrs.creationTime());
 404         System.out.println("atime: " + attrs.lastAccessTime());
 405         System.out.println(" ==============>");
 406         BasicFileAttributes dstAttrs = Files
 407                         .getFileAttributeView(dst, BasicFileAttributeView.class)
 408                         .readAttributes();
 409         System.out.println("mtime: " + dstAttrs.lastModifiedTime());
 410         System.out.println("ctime: " + dstAttrs.creationTime());
 411         System.out.println("atime: " + dstAttrs.lastAccessTime());
 412 
 413         // 1-second granularity
 414         if (attrs.lastModifiedTime().to(TimeUnit.SECONDS) !=
 415             dstAttrs.lastModifiedTime().to(TimeUnit.SECONDS) ||
 416             attrs.lastAccessTime().to(TimeUnit.SECONDS) !=
 417             dstAttrs.lastAccessTime().to(TimeUnit.SECONDS) ||
 418             attrs.creationTime().to(TimeUnit.SECONDS) !=
 419             dstAttrs.creationTime().to(TimeUnit.SECONDS)) {
 420             throw new RuntimeException("Timestamp Copy Failed!");
 421         }

 422         Files.delete(fsPath);
 423     }

 424 
 425     static void test8069211() throws Exception {
 426         // create a new filesystem, copy this file into it
 427         Map<String, Object> env = new HashMap<String, Object>();
 428         env.put("create", "true");
 429         Path fsPath = getTempPath();
 430         try (FileSystem fs = newZipFileSystem(fsPath, env);) {
 431             OutputStream out = Files.newOutputStream(fs.getPath("/foo"));
 432             out.write("hello".getBytes());
 433             out.close();
 434             out.close();
 435         }
 436         try (FileSystem fs = newZipFileSystem(fsPath, new HashMap<String, Object>())) {
 437             if (!Arrays.equals(Files.readAllBytes(fs.getPath("/foo")),
 438                                "hello".getBytes())) {
 439                 throw new RuntimeException("entry close() failed");
 440             }
 441         } catch (Exception x) {
 442             throw new RuntimeException("entry close() failed", x);
 443         } finally {


 607             return;
 608         path = path.toAbsolutePath();
 609         Path parent = path.getParent();
 610         if (parent != null) {
 611             if (Files.notExists(parent))
 612                 mkdirs(parent);
 613         }
 614         Files.createDirectory(path);
 615     }
 616 
 617     private static void rmdirs(Path path) throws IOException {
 618         while (path != null && path.getNameCount() != 0) {
 619             Files.delete(path);
 620             path = path.getParent();
 621         }
 622     }
 623 
 624     // check the content of two paths are equal
 625     private static void checkEqual(Path src, Path dst) throws IOException
 626     {
 627         //System.out.printf("checking <%s> vs <%s>...%n",
 628         //                  src.toString(), dst.toString());
 629 
 630         //streams
 631         byte[] bufSrc = new byte[8192];
 632         byte[] bufDst = new byte[8192];
 633         try (InputStream isSrc = Files.newInputStream(src);
 634              InputStream isDst = Files.newInputStream(dst))
 635         {
 636             int nSrc = 0;
 637             while ((nSrc = isSrc.read(bufSrc)) != -1) {
 638                 int nDst = 0;
 639                 while (nDst < nSrc) {
 640                     int n = isDst.read(bufDst, nDst, nSrc - nDst);
 641                     if (n == -1) {
 642                         System.out.printf("checking <%s> vs <%s>...%n",
 643                                           src.toString(), dst.toString());
 644                         throw new RuntimeException("CHECK FAILED!");
 645                     }
 646                     nDst += n;
 647                 }
 648                 while (--nSrc >= 0) {


 685                     }
 686                     nSrc--;
 687                 }
 688                 bbSrc.flip();
 689                 bbDst.flip();
 690             }
 691 
 692             // Check if source read position is at the end
 693             if (chSrc.position() != chSrc.size()) {
 694                 System.out.printf("src[%s]: size=%d, position=%d%n",
 695                                   chSrc.toString(), chSrc.size(), chSrc.position());
 696                 throw new RuntimeException("CHECK FAILED!");
 697             }
 698 
 699             // Check if destination read position is at the end
 700             if (chDst.position() != chDst.size()) {
 701                 System.out.printf("dst[%s]: size=%d, position=%d%n",
 702                                   chDst.toString(), chDst.size(), chDst.position());
 703                 throw new RuntimeException("CHECK FAILED!");
 704             }















 705         } catch (IOException x) {
 706             x.printStackTrace();
 707         }
 708     }
 709 
 710     private static void fchCopy(Path src, Path dst) throws IOException
 711     {
 712         Set<OpenOption> read = new HashSet<>();
 713         read.add(READ);
 714         Set<OpenOption> openwrite = new HashSet<>();
 715         openwrite.add(CREATE_NEW);
 716         openwrite.add(WRITE);
 717 
 718         try (FileChannel srcFc = src.getFileSystem()
 719                                     .provider()
 720                                     .newFileChannel(src, read);
 721              FileChannel dstFc = dst.getFileSystem()
 722                                     .provider()
 723                                     .newFileChannel(dst, openwrite))
 724         {


   1 /*
   2  * Copyright (c) 2010, 2018, 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 import java.io.File;
  25 import java.io.IOException;
  26 import java.io.InputStream;
  27 import java.io.OutputStream;
  28 import java.net.URI;
  29 import java.net.URLDecoder;
  30 import java.nio.ByteBuffer;
  31 import java.nio.channels.Channels;
  32 import java.nio.channels.FileChannel;
  33 import java.nio.channels.SeekableByteChannel;
  34 import java.nio.file.DirectoryStream;
  35 import java.nio.file.FileAlreadyExistsException;
  36 import java.nio.file.FileSystem;
  37 import java.nio.file.FileSystemAlreadyExistsException;
  38 import java.nio.file.FileSystemException;
  39 import java.nio.file.FileSystems;
  40 import java.nio.file.FileVisitResult;
  41 import java.nio.file.Files;
  42 import java.nio.file.OpenOption;
  43 import java.nio.file.Path;
  44 import java.nio.file.Paths;
  45 import java.nio.file.SimpleFileVisitor;
  46 import java.nio.file.attribute.BasicFileAttributeView;
  47 import java.nio.file.attribute.BasicFileAttributes;
  48 import java.nio.file.spi.FileSystemProvider;
  49 import java.util.ArrayList;
  50 import java.util.Arrays;
  51 import java.util.Collections;
  52 import java.util.Enumeration;
  53 import java.util.HashMap;
  54 import java.util.HashSet;
  55 import java.util.Iterator;
  56 import java.util.LinkedList;
  57 import java.util.List;
  58 import java.util.Map;
  59 import java.util.Random;
  60 import java.util.Set;
  61 import java.util.concurrent.TimeUnit;
  62 import java.util.zip.CRC32;
  63 import java.util.zip.ZipEntry;
  64 import java.util.zip.ZipFile;
  65 import java.util.zip.ZipOutputStream;
  66 
  67 import static java.nio.file.StandardOpenOption.*;
  68 import static java.nio.file.StandardCopyOption.*;
  69 
  70 /*
  71  * Tests various zipfs operations.
  72  *
  73  * @test
  74  * @bug 6990846 7009092 7009085 7015391 7014948 7005986 7017840 7007596
  75  *      7157656 8002390 7012868 7012856 8015728 8038500 8040059 8069211
  76  *      8131067 8034802
  77  * @summary Test Zip filesystem provider
  78  * @modules jdk.zipfs
  79  * @run main ZipFSTester
  80  * @run main/othervm/java.security.policy=test.policy ZipFSTester
  81  */
  82 
  83 public class ZipFSTester {
  84 
  85     public static void main(String[] args) throws Exception {

  86         // create JAR file for test, actual contents don't matter
  87         Path jarFile = Utils.createJarFile("tester.jar",
  88                 "META-INF/MANIFEST.MF",
  89                 "dir1/foo",
  90                 "dir2/bar",
  91                 "dir1/dir3/fooo");
  92 
  93         try (FileSystem fs = newZipFileSystem(jarFile, Collections.emptyMap())) {
  94             test0(fs);
  95             test1(fs);
  96             test2(fs);   // more tests
  97         }
  98 
  99         testStreamChannel();
 100         testTime(jarFile);
 101         test8069211();
 102         test8131067();
 103     }
 104 
 105     private static Random rdm = new Random();
 106 
 107     static void test0(FileSystem fs)
 108         throws Exception
 109     {
 110         List<String> list = new LinkedList<>();
 111         try (ZipFile zf = new ZipFile(fs.toString())) {
 112             Enumeration<? extends ZipEntry> zes = zf.entries();
 113             while (zes.hasMoreElements()) {
 114                 list.add(zes.nextElement().getName());
 115             }
 116             for (String pname : list) {
 117                 Path path = fs.getPath(pname);
 118                 if (!Files.exists(path))
 119                     throw new RuntimeException("path existence check failed!");
 120                 while ((path = path.getParent()) != null) {
 121                     if (!Files.exists(path))
 122                         throw new RuntimeException("parent existence check failed!");
 123                 }
 124             }
 125         }
 126     }
 127 
 128     static void test1(FileSystem fs0)
 129         throws Exception
 130     {
 131         // prepare a src for testing
 132         Path src = getTempPath();
 133         String tmpName = src.toString();
 134         try (OutputStream os = Files.newOutputStream(src)) {
 135             byte[] bits = new byte[12345];
 136             rdm.nextBytes(bits);
 137             os.write(bits);
 138         }
 139 
 140         // clone a fs from fs0 and test on it
 141         Path tmpfsPath = getTempPath();
 142         Map<String, Object> env = new HashMap<String, Object>();
 143         env.put("create", "true");
 144         try (FileSystem copy = newZipFileSystem(tmpfsPath, env)) {
 145             z2zcopy(fs0, copy, "/", 0);
 146 
 147             // copy the test jar itself in
 148             Files.copy(Paths.get(fs0.toString()), copy.getPath("/foo.jar"));
 149             Path zpath = copy.getPath("/foo.jar");
 150             try (FileSystem zzfs = FileSystems.newFileSystem(zpath, null)) {
 151                 Files.copy(src, zzfs.getPath("/srcInjarjar"));
 152             }
 153         }
 154 
 155         try (FileSystem fs = newZipFileSystem(tmpfsPath, new HashMap<String, Object>())) {
 156 
 157             FileSystemProvider provider = fs.provider();
 158             // newFileSystem(path...) should not throw exception
 159             try (FileSystem fsPath = provider.newFileSystem(tmpfsPath, new HashMap<String, Object>())){}
 160             try (FileSystem fsUri = provider.newFileSystem(
 161                      new URI("jar", tmpfsPath.toUri().toString(), null),
 162                      new HashMap<String, Object>()))
 163             {
 164                 throw new RuntimeException("newFileSystem(URI...) does not throw exception");
 165             } catch (FileSystemAlreadyExistsException fsaee) {}
 166 









 167             try {
 168                 provider.newFileSystem(new File(System.getProperty("test.src", ".")).toPath(),
 169                                        new HashMap<String, Object>());
 170                 throw new RuntimeException("newFileSystem() opens a directory as zipfs");
 171             } catch (UnsupportedOperationException uoe) {}
 172 
 173             try {
 174                 provider.newFileSystem(src, new HashMap<String, Object>());
 175                 throw new RuntimeException("newFileSystem() opens a non-zip file as zipfs");
 176             } catch (UnsupportedOperationException uoe) {}
 177 
 178             // walk
 179             walk(fs.getPath("/"));
 180 
 181             // copyin
 182             Path dst = getPathWithParents(fs, tmpName);
 183             Files.copy(src, dst);
 184             checkEqual(src, dst);
 185 
 186             // copy
 187             Path dst2 = getPathWithParents(fs, "/xyz" + rdm.nextInt(100) +
 188                                            "/efg" + rdm.nextInt(100) + "/foo.class");
 189             Files.copy(dst, dst2);
 190             //dst.moveTo(dst2);
 191             checkEqual(src, dst2);
 192 
 193             // delete
 194             Files.delete(dst);
 195             if (Files.exists(dst))
 196                 throw new RuntimeException("Failed!");
 197 
 198             // moveout
 199             Path dst3 = Paths.get(tmpName + "_Tmp");


 234             }
 235 
 236             // rmdirs
 237             try {
 238                 rmdirs(parent);
 239             } catch (IOException x) {
 240                 x.printStackTrace();
 241             }
 242 
 243             // newFileChannel() copy in, out and verify via fch
 244             fchCopy(src, dst);    // in
 245             checkEqual(src, dst);
 246             Path tmp = Paths.get(tmpName + "_Tmp");
 247             fchCopy(dst, tmp);   //  out
 248             checkEqual(src, tmp);
 249             Files.delete(tmp);
 250 
 251             // test channels
 252             channel(fs, dst);
 253             Files.delete(dst);
 254 
 255             // test foo.jar in jar/zipfs #8034802
 256             Path jpath = fs.getPath("/foo.jar");
 257             System.out.println("walking: " + jpath);
 258             try (FileSystem zzfs = FileSystems.newFileSystem(jpath, null)) {
 259                 walk(zzfs.getPath("/"));
 260                 // foojar:/srcInjarjar
 261                 checkEqual(src, zzfs.getPath("/srcInjarjar"));
 262 
 263                 dst = getPathWithParents(zzfs, tmpName);
 264                 fchCopy(src, dst);
 265                 checkEqual(src, dst);
 266                 tmp = Paths.get(tmpName + "_Tmp");
 267                 fchCopy(dst, tmp);   //  out
 268                 checkEqual(src, tmp);
 269                 Files.delete(tmp);
 270 
 271                 channel(zzfs, dst);
 272                 Files.delete(dst);
 273             }
 274         } finally {
 275             Files.deleteIfExists(tmpfsPath);
 276             Files.deleteIfExists(src);
 277         }
 278     }
 279 
 280     static void test2(FileSystem fs) throws Exception {
 281 
 282         Path fs1Path = getTempPath();
 283         Path fs2Path = getTempPath();
 284         Path fs3Path = getTempPath();
 285 
 286         // create a new filesystem, copy everything from fs
 287         Map<String, Object> env = new HashMap<String, Object>();
 288         env.put("create", "true");
 289         FileSystem fs0 = newZipFileSystem(fs1Path, env);
 290 
 291         final FileSystem fs2 = newZipFileSystem(fs2Path, env);
 292         final FileSystem fs3 = newZipFileSystem(fs3Path, env);
 293 
 294         System.out.println("copy src: fs -> fs0...");
 295         z2zcopy(fs, fs0, "/", 0);   // copy fs -> fs1
 296         fs0.close();                // dump to file


 400 
 401         ArrayList<String> files2 = new ArrayList<>();
 402         ArrayList<String> dirs2 = new ArrayList<>();
 403         list(fs4.getPath("/"), files2, dirs2);
 404 
 405         System.out.println("checkEqual: fs vs fs4");
 406         for (String path : files2) {
 407             checkEqual(fs.getPath(path), fs4.getPath(path));
 408         }
 409         System.out.println("walking: fs4");
 410         walk(fs4.getPath("/"));
 411         System.out.println("closing: fs4");
 412         fs4.close();
 413         System.out.printf("failed=%d%n", failed);
 414 
 415         Files.delete(fs1Path);
 416         Files.delete(fs2Path);
 417         Files.delete(fs3Path);
 418     }
 419 
 420     static final int METHOD_STORED     = 0;
 421     static final int METHOD_DEFLATED   = 8;
 422 
 423     static Object[][] getEntries() {
 424         Object[][] entries = new Object[10 + rdm.nextInt(20)][3];
 425         for (int i = 0; i < entries.length; i++) {
 426             entries[i][0] = "entries" + i;
 427             entries[i][1] = rdm.nextInt(10) % 2 == 0 ?
 428                 METHOD_STORED : METHOD_DEFLATED;
 429             entries[i][2] = new byte[rdm.nextInt(8192)];
 430             rdm.nextBytes((byte[])entries[i][2]);
 431         }
 432         return entries;
 433     }
 434 
 435     // check the content of read from zipfs is equal to the "bytes"
 436     private static void checkRead(Path path, byte[] expected) throws IOException {
 437         //streams
 438         try (InputStream is = Files.newInputStream(path)) {
 439             if (!Arrays.equals(is.readAllBytes(), expected)) {
 440                 System.out.printf(" newInputStream <%s> failed...%n", path.toString());
 441                 throw new RuntimeException("CHECK FAILED!");
 442             }
 443         }
 444 
 445         // channels -- via sun.nio.ch.ChannelInputStream
 446         try (SeekableByteChannel sbc = Files.newByteChannel(path);
 447             InputStream is = Channels.newInputStream(sbc)) {
 448 
 449             // check all bytes match
 450             if (!Arrays.equals(is.readAllBytes(), expected)) {
 451                 System.out.printf(" newByteChannel <%s> failed...%n", path.toString());
 452                 throw new RuntimeException("CHECK FAILED!");
 453             }
 454 
 455             // Check if read position is at the end
 456             if (sbc.position() != expected.length) {
 457                 System.out.printf("pos [%s]: size=%d, position=%d%n",
 458                                   path.toString(), expected.length, sbc.position());
 459                 throw new RuntimeException("CHECK FAILED!");
 460             }
 461 
 462             // Check position(x) + read() at the random/specific pos/len
 463             byte[] buf = new byte[1024];
 464             ByteBuffer bb = ByteBuffer.wrap(buf);
 465             for (int i = 0; i < 10; i++) {
 466                 int pos = rdm.nextInt((int)sbc.size());
 467                 int len = rdm.nextInt(Math.min(buf.length, expected.length - pos));
 468                 // System.out.printf("  --> %d, %d%n", pos, len);
 469                 bb.position(0).limit(len);    // bb.flip().limit(len);
 470                 if (sbc.position(pos).position() != pos ||
 471                     sbc.read(bb) != len ||
 472                     !Arrays.equals(buf, 0, bb.position(), expected, pos, pos + len)) {
 473                     System.out.printf("read()/position() failed%n");
 474                 }
 475             }
 476         } catch (IOException x) {
 477             x.printStackTrace();
 478             throw new RuntimeException("CHECK FAILED!");
 479         }
 480     }
 481 
 482     // test entry stream/channel reading
 483     static void testStreamChannel() throws Exception {
 484         Path zpath = getTempPath();
 485         try {
 486             var crc = new CRC32();
 487             Object[][] entries = getEntries();
 488 
 489             // [1] create zip via ZipOutputStream
 490             try (var os = Files.newOutputStream(zpath);
 491                  var zos = new ZipOutputStream(os)) {
 492                 for (Object[] entry : entries) {
 493                    var ze = new ZipEntry((String)entry[0]);
 494                    int method = (int)entry[1];
 495                    byte[] bytes = (byte[])entry[2];
 496                    if (method == METHOD_STORED) {
 497                        ze.setSize(bytes.length);
 498                        crc.reset();
 499                        crc.update(bytes);
 500                        ze.setCrc(crc.getValue());
 501                    }
 502                    ze.setMethod(method);
 503                    zos.putNextEntry(ze);
 504                    zos.write(bytes);
 505                    zos.closeEntry();
 506                 }
 507             }
 508             try (var zfs = newZipFileSystem(zpath, Collections.emptyMap())) {
 509                 for (Object[] e : entries) {
 510                     Path path = zfs.getPath((String)e[0]);
 511                     int method = (int)e[1];
 512                     byte[] bytes = (byte[])e[2];
 513                     // System.out.printf("checking read [%s, %d, %d]%n",
 514                     //                   path.toString(), bytes.length, method);
 515                     checkRead(path, bytes);
 516                 }
 517             }
 518             Files.deleteIfExists(zpath);
 519 
 520             // [2] create zip via zfs.newByteChannel
 521             try (var zfs = newZipFileSystem(zpath, Map.of("create", "true"))) {
 522                 for (Object[] e : entries) {
 523                     //  tbd: method is not used
 524                     try (var sbc = Files.newByteChannel(zfs.getPath((String)e[0]),
 525                                                         CREATE_NEW, WRITE)) {
 526                         sbc.write(ByteBuffer.wrap((byte[])e[2]));
 527                     }
 528                 }
 529             }
 530             try (var zfs = newZipFileSystem(zpath, Collections.emptyMap())) {
 531                 for (Object[] e : entries) {
 532                     checkRead(zfs.getPath((String)e[0]), (byte[])e[2]);
 533                 }
 534             }
 535             Files.deleteIfExists(zpath);
 536 
 537             // [3] create zip via Files.write()/newoutputStream/
 538             try (var zfs = newZipFileSystem(zpath, Map.of("create", "true"))) {
 539                 for (Object[] e : entries) {
 540                     Files.write(zfs.getPath((String)e[0]), (byte[])e[2]);
 541                 }
 542             }
 543             try (var zfs = newZipFileSystem(zpath, Collections.emptyMap())) {
 544                 for (Object[] e : entries) {
 545                     checkRead(zfs.getPath((String)e[0]), (byte[])e[2]);
 546                 }
 547             }
 548             Files.deleteIfExists(zpath);
 549 
 550             // [4] create zip via zfs.newByteChannel, with "method_stored"
 551             try (var zfs = newZipFileSystem(zpath,
 552                     Map.of("create", true, "noCompression", true))) {
 553                 for (Object[] e : entries) {
 554                     try (var sbc = Files.newByteChannel(zfs.getPath((String)e[0]),
 555                                                         CREATE_NEW, WRITE)) {
 556                         sbc.write(ByteBuffer.wrap((byte[])e[2]));
 557                     }
 558                 }
 559             }
 560             try (var zfs = newZipFileSystem(zpath, Collections.emptyMap())) {
 561                 for (Object[] e : entries) {
 562                     checkRead(zfs.getPath((String)e[0]), (byte[])e[2]);
 563                 }
 564             }
 565             Files.deleteIfExists(zpath);
 566 
 567         } finally {
 568             Files.deleteIfExists(zpath);
 569         }
 570     }
 571 
 572     // test file stamp
 573     static void testTime(Path src) throws Exception {
 574         BasicFileAttributes attrs = Files
 575                         .getFileAttributeView(src, BasicFileAttributeView.class)
 576                         .readAttributes();
 577         // create a new filesystem, copy this file into it
 578         Map<String, Object> env = new HashMap<String, Object>();
 579         env.put("create", "true");
 580         Path fsPath = getTempPath();
 581         try (FileSystem fs = newZipFileSystem(fsPath, env)) {

 582             System.out.println("test copy with timestamps...");
 583             // copyin
 584             Path dst = getPathWithParents(fs, "me");
 585             Files.copy(src, dst, COPY_ATTRIBUTES);
 586             checkEqual(src, dst);
 587             System.out.println("mtime: " + attrs.lastModifiedTime());
 588             System.out.println("ctime: " + attrs.creationTime());
 589             System.out.println("atime: " + attrs.lastAccessTime());
 590             System.out.println(" ==============>");
 591             BasicFileAttributes dstAttrs = Files
 592                             .getFileAttributeView(dst, BasicFileAttributeView.class)
 593                             .readAttributes();
 594             System.out.println("mtime: " + dstAttrs.lastModifiedTime());
 595             System.out.println("ctime: " + dstAttrs.creationTime());
 596             System.out.println("atime: " + dstAttrs.lastAccessTime());
 597 
 598             // 1-second granularity
 599             if (attrs.lastModifiedTime().to(TimeUnit.SECONDS) !=
 600                 dstAttrs.lastModifiedTime().to(TimeUnit.SECONDS) ||
 601                 attrs.lastAccessTime().to(TimeUnit.SECONDS) !=
 602                 dstAttrs.lastAccessTime().to(TimeUnit.SECONDS) ||
 603                 attrs.creationTime().to(TimeUnit.SECONDS) !=
 604                 dstAttrs.creationTime().to(TimeUnit.SECONDS)) {
 605                 throw new RuntimeException("Timestamp Copy Failed!");
 606             }
 607         } finally {
 608             Files.delete(fsPath);
 609         }
 610     }
 611 
 612     static void test8069211() throws Exception {
 613         // create a new filesystem, copy this file into it
 614         Map<String, Object> env = new HashMap<String, Object>();
 615         env.put("create", "true");
 616         Path fsPath = getTempPath();
 617         try (FileSystem fs = newZipFileSystem(fsPath, env);) {
 618             OutputStream out = Files.newOutputStream(fs.getPath("/foo"));
 619             out.write("hello".getBytes());
 620             out.close();
 621             out.close();
 622         }
 623         try (FileSystem fs = newZipFileSystem(fsPath, new HashMap<String, Object>())) {
 624             if (!Arrays.equals(Files.readAllBytes(fs.getPath("/foo")),
 625                                "hello".getBytes())) {
 626                 throw new RuntimeException("entry close() failed");
 627             }
 628         } catch (Exception x) {
 629             throw new RuntimeException("entry close() failed", x);
 630         } finally {


 794             return;
 795         path = path.toAbsolutePath();
 796         Path parent = path.getParent();
 797         if (parent != null) {
 798             if (Files.notExists(parent))
 799                 mkdirs(parent);
 800         }
 801         Files.createDirectory(path);
 802     }
 803 
 804     private static void rmdirs(Path path) throws IOException {
 805         while (path != null && path.getNameCount() != 0) {
 806             Files.delete(path);
 807             path = path.getParent();
 808         }
 809     }
 810 
 811     // check the content of two paths are equal
 812     private static void checkEqual(Path src, Path dst) throws IOException
 813     {
 814         System.out.printf("checking <%s> vs <%s>...%n",
 815                           src.toString(), dst.toString());
 816 
 817         //streams
 818         byte[] bufSrc = new byte[8192];
 819         byte[] bufDst = new byte[8192];
 820         try (InputStream isSrc = Files.newInputStream(src);
 821              InputStream isDst = Files.newInputStream(dst))
 822         {
 823             int nSrc = 0;
 824             while ((nSrc = isSrc.read(bufSrc)) != -1) {
 825                 int nDst = 0;
 826                 while (nDst < nSrc) {
 827                     int n = isDst.read(bufDst, nDst, nSrc - nDst);
 828                     if (n == -1) {
 829                         System.out.printf("checking <%s> vs <%s>...%n",
 830                                           src.toString(), dst.toString());
 831                         throw new RuntimeException("CHECK FAILED!");
 832                     }
 833                     nDst += n;
 834                 }
 835                 while (--nSrc >= 0) {


 872                     }
 873                     nSrc--;
 874                 }
 875                 bbSrc.flip();
 876                 bbDst.flip();
 877             }
 878 
 879             // Check if source read position is at the end
 880             if (chSrc.position() != chSrc.size()) {
 881                 System.out.printf("src[%s]: size=%d, position=%d%n",
 882                                   chSrc.toString(), chSrc.size(), chSrc.position());
 883                 throw new RuntimeException("CHECK FAILED!");
 884             }
 885 
 886             // Check if destination read position is at the end
 887             if (chDst.position() != chDst.size()) {
 888                 System.out.printf("dst[%s]: size=%d, position=%d%n",
 889                                   chDst.toString(), chDst.size(), chDst.position());
 890                 throw new RuntimeException("CHECK FAILED!");
 891             }
 892 
 893             // Check position(x) + read() at the specific pos/len
 894             for (int i = 0; i < 10; i++) {
 895                 int pos = rdm.nextInt((int)chSrc.size());
 896                 int limit = rdm.nextInt(1024);
 897                 if (chSrc.position(pos).position() != chDst.position(pos).position()) {
 898                     System.out.printf("dst/src.position(pos failed%n");
 899                 }
 900                 bbSrc.clear().limit(limit);
 901                 bbDst.clear().limit(limit);
 902                 if (chSrc.read(bbSrc) != chDst.read(bbDst) ||
 903                     !bbSrc.flip().equals(bbDst.flip())) {
 904                     System.out.printf("dst/src.read() failed%n");
 905                 }
 906             }
 907         } catch (IOException x) {
 908             x.printStackTrace();
 909         }
 910     }
 911 
 912     private static void fchCopy(Path src, Path dst) throws IOException
 913     {
 914         Set<OpenOption> read = new HashSet<>();
 915         read.add(READ);
 916         Set<OpenOption> openwrite = new HashSet<>();
 917         openwrite.add(CREATE_NEW);
 918         openwrite.add(WRITE);
 919 
 920         try (FileChannel srcFc = src.getFileSystem()
 921                                     .provider()
 922                                     .newFileChannel(src, read);
 923              FileChannel dstFc = dst.getFileSystem()
 924                                     .provider()
 925                                     .newFileChannel(dst, openwrite))
 926         {