Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8020755

URI.resolve() fails when original URI is from a zip/jar/war file

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P3 P3
    • tbd
    • 7
    • core-libs

      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();

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: