Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java.nio.file.Path support in FileSystemResource (with regular createRelative behavior, superseding PathResource) [SPR-16833] #21373

Closed
spring-projects-issues opened this issue May 17, 2018 · 3 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented May 17, 2018

Robert Saenger opened SPR-16833 and commented

org.springframework.core.io.PathResource#createRelative(String) doesn't work correctly if the underlying path refers to a file and not to a directory. The problem of the implementation is, that it doesn't properly distinguish between files an directories. In both cases the implementation returns a Resource whose path is simply extended by the given relative path. This is correct if the path points to a directory but invalid if the path points to a file, e.g. <path-to-file>/<relative path> is always invalid it should be <path-to-file-parent>/<relative-path>.

Suggested fix ist to change the implementation as follows:

/**
 * This implementation creates a PathResource, applying the given path relative
 * to the path of the underlying file of this resource descriptor. It properly
 * distinguishes whether the underlying file of this resource descriptor is a
 * file or directory.
 *
 * @see java.nio.file.Files#isDirectory(Path, java.nio.file.LinkOption...)
 * @see java.nio.file.Path#resolve(String)
 * @see java.nio.file.Path#resolveSibling(String)
 */
@Override
public Resource createRelative(final String relativePath) throws IOException {
      return new PathResource(Files.isDirectory(path) ? path.resolve(relativePath) : path.resolveSibling(relativePath));
}

Since the implementation prevents access to the instance variable path, it is not possible to fix the problem via inheritance and overriding the method. Thus as workaround the entire class may be copied and modified as described above.

 


Affects: 5.0.2

Issue Links:

Referenced from: commits 38f9a7b

@spring-projects-issues
Copy link
Collaborator Author

Zhang Jie commented

According to

* <p>Note: Unlike {@link FileSystemResource}, when building relative resources
* via {@link #createRelative}, the relative path will be built <i>underneath</i>
* the given root: e.g. Paths.get("C:/dir1/"), relative path "dir2" -> "C:/dir1/dir2"!
, maybe it is by design, you can use FileSystemResource instead.

@spring-projects-issues
Copy link
Collaborator Author

Robert Saenger commented

Unfortunately  FileSystemResource doesn't work in my case, since we are using a Path into a java.nio.file.FileSystem which solely provides path instances that do not implement the #toFile method. Thus on invocation of the #toFile method an UnsupportedOperationException is thrown.

If I patch the org.springframework.core.io.PathResource as described above, everything works fine. Thus we are able to resolve relative resources within Zip-Files mounted as com.sun.nio.zipfs.ZipFileSystem.

@spring-projects-issues
Copy link
Collaborator Author

Robert Saenger commented

Maybe a possible solution would be to additionaly provide a path-backed FileSystemResource. One possible implementation could be easily derived from org.springframework.core.io.PathResource if the visibility of instance variable 'path' is changed to protected and createRelative is changed as described above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants