Do valid java.net.URIs for nested archives exist?
Asked Answered
P

1

7

It's possible, although perhaps ill-advised, to read archive formats that are basically renamed .zip files (.ear, .war, .jar, etc.), by using the jar: URI scheme.

For example, the following code works well when the uri variable evaluates to a single, top-level archive, e.g. when uri equals jar:file:///Users/justingarrick/Desktop/test/my_war.war!/

private FileSystem createZipFileSystem(Path path) throws IOException {
    URI uri = URI.create("jar:" + path.toUri().toString());
    FileSystem fs;

    try {
        fs = FileSystems.getFileSystem(uri);
    } catch (FileSystemNotFoundException e) {
        fs = FileSystems.newFileSystem(uri, new HashMap<>());
    }

    return fs;
}

However, the getFileSystem and newFileSystem calls fail with an IllegalArgumentException when the URI contains nested archives, e.g. when uri equals jar:jar:file:///Users/justingarrick/Desktop/test/my_war.war!/some_jar.jar!/ (a .jar inside of a .war).

Is there a valid java.net.URI scheme for nested archive files?

Pamela answered 14/11, 2014 at 16:54 Comment(2)
From memory, I'd say the answer is no. Java still has unfixed bugs around escaping ! in URIs (try adding that bang to the end of a directory name and then adding it to your classpath) so my gut reaction is to say that you're going to have some work to do to get it working the way you want.Waistline
From java source code (java.net.JarURLConnection), the answer is also no: ` int separator = spec.indexOf("!/"); /* * REMIND: we don't handle nested JAR URLs */ ...`Zendejas
P
1

As stated in Jonas Berlin's comment above, the answer is no. From the java.net.JarURLConnection source:

/* get the specs for a given url out of the cache, and compute and
 * cache them if they're not there.
 */
private void parseSpecs(URL url) throws MalformedURLException {
    String spec = url.getFile();

    int separator = spec.indexOf("!/");
    /*
     * REMIND: we don't handle nested JAR URLs
     */
    if (separator == -1) {
        throw new MalformedURLException("no !/ found in url spec:" + spec);
    }

    jarFileURL = new URL(spec.substring(0, separator++));
    entryName = null;

    /* if ! is the last letter of the innerURL, entryName is null */
    if (++separator != spec.length()) {
        entryName = spec.substring(separator, spec.length());
        entryName = ParseUtil.decode (entryName);
    }
}
Pamela answered 15/12, 2014 at 17:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.