Skip to content

Consistent support for non-default NIO.2 FileSystems #35435

@krezovic

Description

@krezovic

I am unsure how to title the issue, or how many issues should I create. There seems to be general problem in Spring's Resource when using NIO.2 FileSystem that's not default filesystem.

For reference, I have used ZipFileSystem that's part of JDK and does not require any additional dependencies

https://docs.oracle.com/en/java/javase/17/docs/api/jdk.zipfs/module-summary.html

When constructing a java.nio.file.Path using FileSystem other than default filesystem, its Path::toFile will always throw UnsupportedOperationException

https://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html#toFile--

Spring's Resource exposes Resource::getFile, and FileSystemResource, which accepts java.nio.file.Path in its constructor, will always end up calling Path::toFile whenever Resource::getFile is called.

It might be a great idea to go through all Resource::getFile usages and replace them with other calls wherever possible. So far, the calls that I've stumbled upon are used to either get the file size or to get the Path itself.

I have stubled upon FileSystemResource handling in Spring WebFlux response, where it explicitly calls "resource.getFile()" only to get its size

https://github.com/spring-projects/spring-framework/blob/main/spring-web/src/main/java/org/springframework/http/codec/ResourceHttpMessageWriter.java#L196-L198

Problem may be reproduced using https://github.com/krezovic/spring-nio-resource by simply running ./mvnw clean verify

I have also added another test that circumvents Resource machinery, and that one works as expected.

Another usage can be found in DataBufferUtils::read, which is called from ResourceRegionEncoder, which is called from ResourceHttpMessageWriter

https://github.com/spring-projects/spring-framework/blob/main/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java#L226

Final issue I have found with NIO.2 and Spring Framework is in FileSystemUtils::copyRecursively, where on Windows I get a ProviderMismatchException

java.nio.file.ProviderMismatchException
	at java.base/sun.nio.fs.WindowsPath.toWindowsPath(WindowsPath.java:389)
	at java.base/sun.nio.fs.WindowsPath.resolve(WindowsPath.java:596)
	at java.base/sun.nio.fs.WindowsPath.resolve(WindowsPath.java:42)
	at org.springframework.util.FileSystemUtils$2.preVisitDirectory(FileSystemUtils.java:133)
	at org.springframework.util.FileSystemUtils$2.preVisitDirectory(FileSystemUtils.java:130)
	at java.base/java.nio.file.Files.walkFileTree(Files.java:2816)
	at org.springframework.util.FileSystemUtils.copyRecursively(FileSystemUtils.java:130)

Test is available in reproducer. This way one can easily unpack a ZIP file.

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions