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?
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With