Path -> URI -> Path round trip fails for lazily created zip file systems
Xueming Shen
xueming.shen at oracle.com
Fri Dec 27 11:20:43 PST 2013
Hi Philippe,
I've file a new issue into the bug system.
https://bugs.openjdk.java.net/browse/JDK-8031077
The "realPath" need to be check and set, if null (in case of "create
new"), before to be added
into the map "filesystems". The check is to obtain the real path to
check whether or not the
filesystem (may represented by different url) has been open already,
throw FSAEE if yet, as
the API spec requests.
-Sherman
On 12/25/13 7:23 AM, Philippe Marschall wrote:
> When you create a ZIP file system on a zip file that doesn’t exist
> (option ”create" set to "false”) then the following will fail
>
> Paths.get(path.toUri())
>
> This issue is that in this case the file system is stored under a null
> key in ZipFileSystemProvider#filesystems instead of the real path
> (this may break other things as well). It seems to be caused by the
> following code in ZipFileSystemProvider.newFileSystem(URI, Map<String,
> ?>)
>
> public FileSystem newFileSystem(URI uri, Map<String, ?> env)
> throws IOException
> {
> Path path = uriToPath(uri);
> synchronized(filesystems) {
> Path realPath = null;
> if (ensureFile(path)) {
> realPath = path.toRealPath();
> if (filesystems.containsKey(realPath))
> throw new FileSystemAlreadyExistsException();
> }
> ZipFileSystem zipfs = null;
> try {
> zipfs = new ZipFileSystem(this, path, env);
> } catch (ZipError ze) {
> String pname = path.toString();
> if (pname.endsWith(".zip") || pname.endsWith(".jar"))
> throw ze;
> // assume NOT a zip/jar file
> throw new UnsupportedOperationException();
> }
> filesystems.put(realPath, zipfs);
> return zipfs;
> }
> }
>
> The problem is that when “path” does not exist then #ensureFile will
> return false. In this case realPath will remain null. I don’t know why
> this check is done there so I’m not sure what the fix is.
>
> A simple test case for this is
>
>
> @Test
> public void jarToUriRegression() throws IOException {
> Path jarFolder = Files.createTempDirectory("jartest");
> try {
> Path jarFile = jarFolder.resolve("test.jar");
> try {
> Map<String, String> env = Collections.singletonMap("create", "true");
> URI uri = URI.create("jar:" + jarFile.toUri());
> try (FileSystem jarfs = FileSystems.newFileSystem(uri, env)) {
> Path p = jarfs.getPath("hello.txt");
> assertNotNull(Paths.get(p.toUri()));
> }
> } finally {
> Files.delete(jarFile);
> }
> } finally {
> Files.delete(jarFolder);
> }
> }
>
> I tested with the latest b121 of JDK8.
More information about the nio-dev
mailing list