> 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.

Reply via email to