> > > This is why I put the Ant developers in CC. The correct way would be
> > > to look at the *decoded* path (not just getPath() because this is also
> > > one of the "famous" traps in the URL class - one reason why it should
> > > be avoided in favor of URI). URL.toURI().getPath() is most safe to fix
> > > the issue in Apache Ant
> >
> > Part of the reason for this certainly is that the code has been written
> > before the URI class even existed.
> >
> > > (Stefan Bodewig: Should I open an issue in Ant?).
> >
> > Yes, please do. Thanks Uwe.
> 
> I opened: https://bz.apache.org/bugzilla/show_bug.cgi?id=59130
> 
> > > Maybe Ant developers can fix this code in later versions to handle
> > > URLs more correct.
> >
> > +1
> 
> Unfortunately this is not the only issue caused by this. After I tried to 
> build
> Lucene with the patch applied, the next candidate for the issue broke:
> Apache Ivy. It was no longer able to load the ivy-settings.xml file from its 
> JAR
> file.
> 
> The reason here is another one: It constructs the JAR file URL on its own (it
> looks like this), but does not add the #release fragment. And because of this,
> JarURLConnection does not find the file...:
> 
> [...] multiple parent causes [...]
> Caused by: java.io.FileNotFoundException: JAR entry
> org/apache/ivy/core/settings/ivysett/ivysettings-public.xml not found in
> C:\Users\Uwe Schindler\.ant\lib\ivy-2.3.0.jar
>         at
> sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.jav
> a:142)
>         at
> sun.net.www.protocol.jar.JarURLConnection.getInputStream(JarURLConnec
> tion.java:150)
>         at
> org.apache.ivy.util.url.BasicURLHandler.openStream(BasicURLHandler.java:1
> 71)
>         at
> org.apache.ivy.util.url.URLHandlerDispatcher.openStream(URLHandlerDispat
> cher.java:74)
>         at
> org.apache.ivy.core.settings.XmlSettingsParser.doParse(XmlSettingsParser.j
> ava:157)
>         at
> org.apache.ivy.core.settings.XmlSettingsParser.parse(XmlSettingsParser.java
> :183)
>         at
> org.apache.ivy.core.settings.XmlSettingsParser.includeStarted(XmlSettingsP
> arser.java:435)
>         at
> org.apache.ivy.core.settings.XmlSettingsParser.startElement(XmlSettingsPar
> ser.java:211)
>         ... 35 more
> 
> So it looks like the Multi-release JAR file patch also breaks the other way
> round: Code constructing JAR URLs according to the standard no longer work.
> In my opinion, the JAR URLs should not change at all and the code should
> transparently choose the right release version. Maybe add a fragment only
> to explicitly state a specific version (so one would be able to load the Java 
> 7
> version). But this could also be done using the META-INF/... path. The default
> handling should be that "old" and (I think they are standardized) JAR URLs
> still works as they should - not requiring the fragment!

I tried another project (a private one) and it failed in similar ways while 
loading XSL templates. This project produced no self-crafted jar:-URLs; instead 
it relied on relative URL resolving (the same applies to Apache Ivy).

A common pattern (especially in the "XML world") is to have relative links in 
your files, e.g. an XSLT file that includes another ones. If you place those 
XSL or XML files containing relative links in a JAR file, with previous Java 
versions everything worked as it should. You started the XML parser with the 
URL returned by the classloader and it was able to also resolve relative links 
between the files (because the jar: URL protocol correctly supports relative 
resolving of paths). So  xml/xsl file containing a reference to another file in 
same package using a filename like <include src="./otherfile.xsl"/> works 
perfectly with the JAR URL protocol. If the original file had a URL like 
"jar:file:....!/package/master.xsl" and this was passed to XML parser [e.g, 
like TranformerFactory#newTransformer(new 
StreamSource(classloader.getResource("package/master.xsl ").toString())], the 
XML parser would load "jar:file:....!/package/otherfile.xsl"

But because the fragment is lost during resolving relative URLs, this no longer 
works with Multi-Release JAR files. It looks like JARURLConnection throws 
FileNotFoundException without the #release fragment.

I hope this helps to see why using fragments as part of the identifier is not 
quite correct in the URL world. I'd use some other way to refer to specific 
versions. At least let the no-fragment case always load the version-based file. 
Only use a fragment to refer to another version.

Uwe

Reply via email to