> On 28 Apr 2016, at 12:20, Steve Drach <steve.dr...@oracle.com> wrote: > > >> On Apr 28, 2016, at 12:03 PM, Alan Bateman <alan.bate...@oracle.com> wrote: >> >> >> >> On 28/04/2016 19:53, Steve Drach wrote: >>> : >>> Yes, and for regular jar files, that worked fine, but when we tried it with >>> a multi-release jar we found it by passed the part of JarLoader where we >>> open the jar file as a runtime jar, so, for example, this code fails to >>> retrieve the correct versioned entry, returning instead the base entry. >>> >>> URL[] urls = { new URL(“jar:file:/foo/multi-release.jar!/“) }; >>> URLClassLoader cldr = new URLClassLoader(urls); >>> Class<?> vcls = cldr.loadClass("version.Version”); >>> >>> The change just corrects the logic when working with a “jar:…..!/“ URL. >>> >>> >> Can you double check the URLClassLoader spec? > > We discussed it. It seems the spec might be deficit with respect to > "jar:file:/foo/multi-release.jar!/“ type URLs, but it didn’t matter when it > referred to a legacy jar file. >
It appears to be an undocumented “feature" that URLClassLoader can accept base jar-scheme URLs such as: jar:file/….!/ jar:http/….!/ by virtue of those URLs being passed to URLClassPath, which is contrary to what is stated on URLClassLoader: "Any URL that ends with a '/' is assumed to refer to a directory. Otherwise, the URL is assumed to refer to a JAR file which will be opened as needed.” The above only reliably applies to file-scheme URLs. Here is the original logic: String file = url.getFile(); if (file != null && file.endsWith("/")) { if ("file".equals(url.getProtocol())) { return new FileLoader(url); <—— exploded class loading } else { return new Loader(url); <—— uses URL connection, can process the jar file referenced by jar:file:/…!/ } } else { return new JarLoader(url, jarHandler, lmap); <—— fall back, always the URL references a jar file } Paul.