--- old/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java 2019-12-06 13:08:26.022584300 -0800 +++ new/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java 2019-12-06 13:08:24.769010400 -0800 @@ -1125,27 +1125,21 @@ /** * Attempt to return a file URL by resolving input against a base file - * URL. The input is an absolute or relative file URL that encodes a - * file path. - * - * @apiNote Nonsensical input such as a Windows file path with a drive - * letter cannot be disambiguated from an absolute URL so will be rejected - * (by returning null) by this method. - * + * URL. * @return the resolved URL or null if the input is an absolute URL with * a scheme other than file (ignoring case) * @throws MalformedURLException */ static URL tryResolveFile(URL base, String input) throws MalformedURLException { - int index = input.indexOf(':'); - boolean isFile; - if (index >= 0) { - String scheme = input.substring(0, index); - isFile = "file".equalsIgnoreCase(scheme); - } else { - isFile = true; + URL retVal = new URL(base, input); + if (input.indexOf(':') >= 0 && + !"file".equalsIgnoreCase(retVal.getProtocol())) { + // 'input' contains a ':', which might be a scheme, or might be + // a Windows drive letter. If the protocol for the resolved URL + // isn't "file:", it should be ignored. + return null; } - return (isFile) ? new URL(base, input) : null; + return retVal; } /** --- old/test/jdk/jdk/internal/loader/URLClassPath/JarClassPathFileEntry.java 2019-12-06 13:08:33.422430700 -0800 +++ new/test/jdk/jdk/internal/loader/URLClassPath/JarClassPathFileEntry.java 2019-12-06 13:08:32.154173400 -0800 @@ -33,8 +33,8 @@ /* * @test - * @bug 8216401 - * @summary Test loading of JAR Class-Path entry with file: scheme + * @bug 8216401 8235361 + * @summary Test classloading via JAR Class-Path entries * @library /test/lib * * @run main/othervm JarClassPathFileEntry @@ -52,6 +52,19 @@ private final static Path CONTEXT_JAR_PATH = Paths.get(TEST_CLASSES, "Context.jar"); public static void main(String[] args) throws Throwable { + String fileScheme = "file:" + (IS_WINDOWS ? toUnixPath(OTHER_JAR_PATH.toString()) + : OTHER_JAR_PATH.toString()); + doTest(fileScheme); + + if (IS_WINDOWS) { + // Relative URL encoding of absolute path, e.g. /C:\\path\\to\\file.jar + String driveLetter = "/" + OTHER_JAR_PATH; + doTest(driveLetter); + } + } + + /* Load a class from Other.jar via the given Class-Path entry */ + private static void doTest(String classPathEntry) throws Throwable { // Create Other.class in OTHER_DIR, off the default classpath byte klassbuf[] = InMemoryJavaCompiler.compile("Other", "public class Other {}"); @@ -72,8 +85,6 @@ Attributes attrs = mf.getMainAttributes(); attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0"); - String classPathEntry = "file:" + (IS_WINDOWS ? toUnixPath(OTHER_JAR_PATH.toString()) - : OTHER_JAR_PATH.toString()); attrs.put(Attributes.Name.CLASS_PATH, classPathEntry); System.out.println("Creating Context.jar with Class-Path: " + classPathEntry);