Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.net.URI.relativize doesn't work with JAR URIs

Tags:

java

uri

I have two URI objects. One is pointing to a folder in a JAR file, and another is pointing to a file in the same JAR file. The file is in a subfolder of the directory specified by the first URI. I like to create a relative URI so the resulting URI only containing the relative path to the file in the JAR.

  • Folder URI

    jar:file:/C:/Users/inagy/.m2/repository/hu/inagy/my-config-artifact/2.0-SNAPSHOT/my-config-artifact-2.0-SNAPSHOT.jar!/conf/
    
  • Resource URI

    jar:file:/C:/Users/inagy/.m2/repository/hu/inagy/my-config-artifact/2.0-SNAPSHOT/my-config-artifact-2.0-SNAPSHOT.jar!/conf/somesubpath/someconfig.xml
    
  • After calling folderUri.relativize(resourceURI) i'm expecting the following URI as a result:

    somesubpath/someconfig.xml
    

However i get resourceURI back which mean according to the URI class's Javadoc that the JDK code find this two paths non relative to each other.

Is this a bug or i'm doing something wrong?

like image 878
NagyI Avatar asked Oct 24 '12 09:10

NagyI


1 Answers

I've been mildly annoyed by this too. The answer has nothing do to with the semantics of JAR files—it has to do with the syntax of jar: URIs. To be "relativized," a URI has to be hierarchical and not opaque. You will note from the JavaDoc for java.net.URI that:

At the highest level a URI reference (hereinafter simply "URI") in string form has the syntax

[scheme:]scheme-specific-part[#fragment]

...

An opaque URI is an absolute URI whose scheme-specific part does not begin with a slash character ('/'). Opaque URIs are not subject to further parsing.

...

A hierarchical URI is subject to further parsing according to the syntax

[scheme:][//authority][path][?query][#fragment]

A JAR URI like jar:file:///home/me/foo.jar!/conf/ is parsed as:

  • scheme = jar
  • scheme-specific-part = file:///home/me/foo.jar!/conf/
  • fragment = (none)

Because the scheme-specific-part does not begin with "/," it cannot be considered a hierarchical URI. The URI class does not treat jar: (or any) URIs specially, so it cannot recognize that the file:// part is a nested URI that is hierarchical.

Since jar: URIs are opaque and not hierarchical, they are subject to the behavior documented for URI#relativize():

The relativization of the given URI against this URI is computed as follows:

  1. If either this URI or the given URI are opaque, [...], then the given URI is returned.

EDIT: Left out a crucial part about opaque URIs.

like image 58
Tim Yates Avatar answered Nov 09 '22 19:11

Tim Yates