Hi, can you please review the following change which fixes a problem with UNC paths on the Windows class path:
http://cr.openjdk.java.net/~simonis/webrevs/2017/8178726/ https://bugs.openjdk.java.net/browse/JDK-8178726 I would appreciate if somebody could run this trough JPRT for me. I won't be available until Tuesday after Easter so there's some time for testing :) Here comes the detailed problem description (also included in the bug report): If we set the classpath to a UNC share (e.g. '-cp \\foo\bar\classes') java won't be able to find classes there. This is also true if we set the classpath to a drive letter which maps to a network drive (e.g. '-cp Z:\classes' where 'Z:' is a short-cut for '\\foo\bar'). This error is clearly a regression and should be fixed before Java 9 GA. The problem is caused by the refactoring of the application class loader: Before Java 9 the application class loader was a URLClassLoader (actually sun.misc.Launcher$AppClassLoader which extends URLClassLoader). It took the classpath from the "java.class.path" property and transformed it into a File[] by calling Launcher.getClassPath(). This File[] was then converted into a URL[] by calling Launcher.pathToURLs() which in turn called Launcher.getFileURL() which finally called sun.net.www.ParseUtil.fileToEncodedURL() to convert a File into an URL. This last function explicitly creates URLs with protocol 'file' and empty authority (i.e. if the File contained an authority part like "\\foo" in "\\foo\bar\classs"), this was saved in the path part of the URL (i.e. 'return new URL("file", "", path)'); Later, these URLs were used to access classes on the classpath. This was done by creating new File objects from the path components of the corresponding URLs and because these path components already contained the full UNC path, everything worked fine. In JDK 9 now, the legacy class path is constructed in jdk.internal.loader.ClassLoaders. It also takes the "java.class.path" property as a starting point but calls addClassPathToUCP() which in turn calls toFileURL() which finally uses 'Paths.get(s).toRealPath().toUri().toURL()' to transform a string 's' into an URL. This conversion creates URLs where the authority part contains the hostname and the path component contains the remaining path from the UNC paths in the classpath. The problem is now that during class loading, the new application class loader jdk.internal.loader.ClassLoaders$AppClassLoader calls jdk.internal.loader.BuiltinClassLoader.loadClass() which calls loadClassOrNull() which calls findClassOnClassPathOrNull() which calls jdk.internal.loader.URLClassPath.getResource(). The class URLClassPath has a list of all the previously created URLs for each entry of the classpath. For each of these URLs it creates a jdk.internal.loader.URLClassPath$Loader by calling getLoader(). If the corresponding URL represents a file, it will create a jdk.internal.loader.URLClassPath$FileLoader (which derives from URLClassPath$Loader). The FileLoader class uses the file component of the URL to construct a File object for accessing the underlying ressources. But unlike the jdk8 case, the file part of the URL now only contains the path component WITHOUT the authority (i.e. 'host') part. This will be interpreted as a relative path realtively to the current drive and obviously fail. Thanks, Volker