FULL PRODUCT VERSION :
java version " 1.7.0_21 "
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) Client VM (build 23.21-b01, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Windows 7, Windows XP
A DESCRIPTION OF THE PROBLEM :
URI.resolve() should be able to use a fully qualified URI to resolve a relative URI to a full path. Instead it just creates a new URI with the relative path. This only happens if the original URI was obtained from a zip file - or a jar or war file, which are of course just zip files.
The the most obvious way this will happen is when using ClassLoader.getResource() to obtain a URL which will end up being a URL in a jar file.
This has apparently been broken since at least Java 1.5
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile a class with a public static void main() and package it in a jar file along with a pair of text files, then run it using that jar file as the classpath. The class would do something like this:
ClassLoader cl=this.getClass().getClassLoader();
URL url=cl.getResource( " /org/foo/bar.txt " );
URI uri=url.toURI();
System.out.println(uri.toString());
URI uri2=uri.resolve( " bash.txt " );
System.out.println(uri2.toString());
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When the original resource is found in a .jar file in the classpath, URI.toString() provides a name like " jar:file:c:/x.jar!/org/foo/bar.txt " . The derived URI's toString() should be similar, such as " jar:file:c:/x.jar!/org/foo/bash.txt " .
ACTUAL -
Instead, the derived URI is just " bash.txt " . Of course if one attempts to use it to open the resource, this will fail.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
ClassLoader cl=this.getClass().getClassLoader();
URL url=cl.getResource( " /org/foo/bar.txt " );
URI uri=url.toURI();
System.out.println(uri.toString());
URI uri2=uri.resolve( " bash.txt " );
System.out.println(uri2.toString());
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Best workaround is just to use the original URI's toString() to obtain a URI string, chop off everything after the last " / " , create a new URI by appending the relative path to that, then pass the result to new URI(str).normalize();
java version " 1.7.0_21 "
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) Client VM (build 23.21-b01, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Windows 7, Windows XP
A DESCRIPTION OF THE PROBLEM :
URI.resolve() should be able to use a fully qualified URI to resolve a relative URI to a full path. Instead it just creates a new URI with the relative path. This only happens if the original URI was obtained from a zip file - or a jar or war file, which are of course just zip files.
The the most obvious way this will happen is when using ClassLoader.getResource() to obtain a URL which will end up being a URL in a jar file.
This has apparently been broken since at least Java 1.5
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile a class with a public static void main() and package it in a jar file along with a pair of text files, then run it using that jar file as the classpath. The class would do something like this:
ClassLoader cl=this.getClass().getClassLoader();
URL url=cl.getResource( " /org/foo/bar.txt " );
URI uri=url.toURI();
System.out.println(uri.toString());
URI uri2=uri.resolve( " bash.txt " );
System.out.println(uri2.toString());
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When the original resource is found in a .jar file in the classpath, URI.toString() provides a name like " jar:file:c:/x.jar!/org/foo/bar.txt " . The derived URI's toString() should be similar, such as " jar:file:c:/x.jar!/org/foo/bash.txt " .
ACTUAL -
Instead, the derived URI is just " bash.txt " . Of course if one attempts to use it to open the resource, this will fail.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
ClassLoader cl=this.getClass().getClassLoader();
URL url=cl.getResource( " /org/foo/bar.txt " );
URI uri=url.toURI();
System.out.println(uri.toString());
URI uri2=uri.resolve( " bash.txt " );
System.out.println(uri2.toString());
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Best workaround is just to use the original URI's toString() to obtain a URI string, chop off everything after the last " / " , create a new URI by appending the relative path to that, then pass the result to new URI(str).normalize();