Just for reference - this came up while debugging an issue, that one of our users of Apache Ant project raised here https://bz.apache.org/bugzilla/show_bug.cgi?id=62764#c8
-Jaikiran On 04/10/18 3:06 PM, Jaikiran Pai wrote: > 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 >