Please consider the following trivial code: import java.util.jar.*; import java.io.*;
public class JarFileTest { public static void main(final String[] args) throws Exception { final String tmpDir = System.getProperty("java.io.tmpdir"); try { final JarFile jarFile = new JarFile(tmpDir + File.separator + "*"); } catch (IOException ioe) { System.out.println("Got the expected IOException " + ioe); } } } The constructor of the JarFile is passed a string which intentionally is an (wildcard) invalid path. The above code (as expected) throws an IOException on *nix systems across various version of Java (tested against Java 8, 11). The same code throws an IOException (as expected) in Java 8 on Windows OS too. However, in Java 11, on Windows OS, this code throws a different exception (java.nio.file.InvalidPathException) which isn't IOException or a subclass of it: Exception in thread "main" java.nio.file.InvalidPathException: Illegal char <*> at index 38: C:\Users\someone\AppData\Local\Temp\1\* at java.base/sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182) at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153) at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77) at java.base/sun.nio.fs.WindowsPath.parse(WindowsPath.java:92) at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:229) at java.base/java.io.File.toPath(File.java:2290) at java.base/java.util.zip.ZipFile$Source.get(ZipFile.java:1220) at java.base/java.util.zip.ZipFile$CleanableResource.<init>(ZipFile.java:727) at java.base/java.util.zip.ZipFile$CleanableResource.get(ZipFile.java:845) at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:245) at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:175) at java.base/java.util.jar.JarFile.<init>(JarFile.java:341) at java.base/java.util.jar.JarFile.<init>(JarFile.java:312) at java.base/java.util.jar.JarFile.<init>(JarFile.java:251) at JarFileTest.main(JarFileTest.java:8) The javadoc of JarFile constructor(s) mentions that: * @throws IOException if an I/O error has occurred Given that the javadoc doesn't mention anything about this other exception, would this throwing of java.nio.file.InvalidPathException be considered a bug in the implementation? If this indeed is considered a bug, it appears to be the code in java.util.zip.ZipFile$Source.get method which calls File#toPath(), which as per its javadoc is indeed expected to throw an java.nio.file.InvalidPathException if a Path cannot be constructed out of the File. Looking at the implementation of the underlying java.nio.file.FileSystem on *nix and Windows, they differ when it comes to whether or not the exception gets thrown (Unix one seems to always return a result). But keeping the implementation of java.nio.file.FileSystem aside, I guess the java.util.zip.ZipFile$Source.get code needs to have a catch block for the InvalidPathException to wrap that into a IOException? Something like: # HG changeset patch # User Jaikiran Pai <jaikiran....@gmail.com> # Date 1538645309 -19800 # Thu Oct 04 14:58:29 2018 +0530 # Node ID ff1bfd8cc9a3b385716fa5191bb68989d552f87e # Parent 8705c6d536c5c197d0210acccf145ebc48f90227 Wrap and throw an IOException when a InvalidPathException is thrown diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java --- a/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -35,6 +35,7 @@ import java.lang.ref.Cleaner.Cleanable; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.nio.file.InvalidPathException; import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.Files; import java.util.ArrayDeque; @@ -1218,8 +1219,13 @@ static Source get(File file, boolean toDelete) throws IOException { - Key key = new Key(file, - Files.readAttributes(file.toPath(), BasicFileAttributes.class)); + final Key key; + try { + key = new Key(file, + Files.readAttributes(file.toPath(), BasicFileAttributes.class)); + } catch (InvalidPathException ipe) { + throw new IOException(ipe); + } Source src; synchronized (files) { src = files.get(key); Any thoughts? -Jaikiran