I am trying to use NIO FileSystem to access a jar inside another jar. Call the outside jar my-outer.jar and the inner my-inner.jar (Using Java 8 and Windows 7 but I think that is not the issue)
I am using the following code
String zipfilePath = "c:/testfs/my-outer.jar!/my-inner.jar";
Path path = Paths.get(zipfilePath);
try(ZipFileSystem zipfs = (ZipFileSystem) FileSystems.newFileSystem(path, null))
{ ... }
but I am getting the exception below when trying to create that newFileSystem:
Exception in thread "main" java.nio.file.FileSystemNotFoundException: C:\testfs\my-outer.jar!\my-inner.jar
Note that if I just use the outer jar as the FileSystem, that works perfectly fine and I can read and write files from it beautifully. It's just when I try to reach into the inner archive that the troubles begin.
Doesn't FileSystem support the JarURLConnection notation?
A JAR file is actually just a ZIP file. It can contain anything - usually it contains compiled Java code (*.
You can use the JAR file editor to view or edit JAR file information that is stored in a data development project. If you make changes to JAR file information using the editor, you must deploy the JAR file to the database server again to apply the changes to the server version of the JAR file.
As said by vbezhenear and as experimented by myself the JarURLConnection notation in the form c:/testfs/my-outer.jar!/my-inner.jar
seems not implemented by the factory method FileSystems.newFileSystem(Path path, ClassLoader loader)
.
But you can still access the inner jar like this:
Path outerPath = Paths.get("c:/testfs/my-outer.jar");
try (FileSystem outerFS = FileSystems.newFileSystem(outerPath, null)) {
Path innerPath = outerFS.getPath("/my-inner.jar");
try (FileSystem innerFS = FileSystems.newFileSystem(innerPath, null)) {
...
}
}
--UPDATE--
If you try to use an URI
instead of a Path
you can create a ZipFileSystem
like this
URI uri = URI.create("jar:file:/home/orto/stackoverflow/outer.jar!/inner.jar");
Map<String,String> env = Collections.emptyMap();
try(ZipFileSystem zipfs = (ZipFileSystem)FileSystems.newFileSystem(uri,env))
{...}
But no luck you get access to the outer.jar
and not the inner.jar
If you look at the source code of JarFileSystemProvider
you see
@Override
protected Path uriToPath(URI uri) {
String scheme = uri.getScheme();
if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) {
throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
}
try {
String uristr = uri.toString();
int end = uristr.indexOf("!/");
uristr = uristr.substring(4, (end == -1) ? uristr.length() : end);
uri = new URI(uristr);
return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null))
.toAbsolutePath();
} catch (URISyntaxException e) {
throw new AssertionError(e); //never thrown
}
}
The path is cut up before the first "!"
. So there is no way to directly create a file system on the inside jar from the newFileSystem
method.
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