Index: /trunk/src/org/openstreetmap/josm/io/session/SessionReader.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/session/SessionReader.java	(revision 14723)
+++ /trunk/src/org/openstreetmap/josm/io/session/SessionReader.java	(revision 14724)
@@ -13,10 +13,11 @@
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
 import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.List;
@@ -24,7 +25,5 @@
 import java.util.Map.Entry;
 import java.util.TreeMap;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
-import java.util.zip.ZipFile;
+import java.util.stream.Stream;
 
 import javax.swing.JOptionPane;
@@ -151,7 +150,7 @@
     private static final Map<String, Class<? extends SessionLayerImporter>> sessionLayerImporters = new HashMap<>();
 
-    private URI sessionFileURI;
+    private Path sessionFile;
     private boolean zip; // true, if session file is a .joz file; false if it is a .jos file
-    private ZipFile zipFile;
+    private FileSystem zipFile;
     private List<Layer> layers = new ArrayList<>();
     private int active = -1;
@@ -292,5 +291,5 @@
          *     - file inside zip archive:
          *         "layers/01/data.osm"
-         *     - relativ to the .joz file:
+         *     - relative to the .joz file:
          *         "../save/data.osm"           ("../" steps out of the archive)
          * @param uriStr URI as string
@@ -308,8 +307,5 @@
                 }
             } else if (inZipPath != null) {
-                ZipEntry entry = zipFile.getEntry(inZipPath);
-                if (entry != null) {
-                    return zipFile.getInputStream(entry);
-                }
+                return Files.newInputStream(zipFile.getPath(inZipPath));
             }
             throw new IOException(tr("Unable to locate file  ''{0}''.", uriStr));
@@ -345,5 +341,5 @@
                                 // relative to session file - "../" step out of the archive
                                 String relPath = uri.getPath().substring(3);
-                                return new File(sessionFileURI.resolve(relPath));
+                                return sessionFile.resolveSibling(relPath).toFile();
                             } else {
                                 // file inside zip archive
@@ -352,5 +348,5 @@
                             }
                         } else
-                            return new File(sessionFileURI.resolve(uri));
+                            return sessionFile.resolveSibling(uriStr).toFile();
                     }
                 } else
@@ -704,5 +700,5 @@
     public void loadSession(File sessionFile, boolean zip, ProgressMonitor progressMonitor) throws IllegalDataException, IOException {
         try (InputStream josIS = createInputStream(sessionFile, zip)) {
-            loadSession(josIS, sessionFile.toURI(), zip, progressMonitor != null ? progressMonitor : NullProgressMonitor.INSTANCE);
+            loadSession(josIS, sessionFile.toPath(), zip, progressMonitor != null ? progressMonitor : NullProgressMonitor.INSTANCE);
         }
     }
@@ -711,8 +707,15 @@
         if (zip) {
             try {
-                zipFile = new ZipFile(sessionFile, StandardCharsets.UTF_8);
-                return getZipInputStream(zipFile);
-            } catch (ZipException ex) {
-                throw new IOException(ex);
+                // read zip using ZipFileSystem/ZipFileSystemProvider
+                zipFile = FileSystems.newFileSystem(new URI("jar:" + sessionFile.toURI()), Collections.emptyMap());
+                try (Stream<Path> content = Files.list(zipFile.getPath("/"))) {
+                    final Path jos = content
+                            .filter(path -> Utils.hasExtension(path.getFileName().toString(), "jos"))
+                            .findFirst()
+                            .orElseThrow(() -> new IllegalDataException(tr("expected .jos file inside .joz archive")));
+                    return Files.newInputStream(jos);
+                }
+            } catch (URISyntaxException e) {
+                throw new IOException(e);
             }
         } else {
@@ -721,24 +724,8 @@
     }
 
-    private static InputStream getZipInputStream(ZipFile zipFile) throws IOException, IllegalDataException {
-        ZipEntry josEntry = null;
-        Enumeration<? extends ZipEntry> entries = zipFile.entries();
-        while (entries.hasMoreElements()) {
-            ZipEntry entry = entries.nextElement();
-            if (Utils.hasExtension(entry.getName(), "jos")) {
-                josEntry = entry;
-                break;
-            }
-        }
-        if (josEntry == null) {
-            error(tr("expected .jos file inside .joz archive"));
-        }
-        return zipFile.getInputStream(josEntry);
-    }
-
-    private void loadSession(InputStream josIS, URI sessionFileURI, boolean zip, ProgressMonitor progressMonitor)
+    private void loadSession(InputStream josIS, Path sessionFile, boolean zip, ProgressMonitor progressMonitor)
             throws IOException, IllegalDataException {
 
-        this.sessionFileURI = sessionFileURI;
+        this.sessionFile = sessionFile;
         this.zip = zip;
 
