-
Enhancement
-
Resolution: Unresolved
-
P4
-
None
-
None
-
generic
-
generic
A DESCRIPTION OF THE PROBLEM :
When providing custom FileSystemProvider the ZipFile uses the system one instead of the custom one. This prevents providing any byte channels for files which deals with zip files.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the program with -Djava.nio.file.spi.DefaultFileSystemProvider=Program$CustomFileSystemProvider
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The program does not fail with java.io.FileNotFoundException: test.zip (The system cannot find the file specified)
ACTUAL -
The program fails with java.io.FileNotFoundException: test.zip (The system cannot find the file specified)
---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.AccessMode;
import java.nio.file.CopyOption;
import java.nio.file.DirectoryStream;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileTime;
import java.nio.file.attribute.UserPrincipalLookupService;
import java.nio.file.spi.FileSystemProvider;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipFile;
public class Program {
public static void main(String[] args) throws IOException {
String fileName = "test.zip";
byte[] bytes = Files.readAllBytes(Path.of(fileName));
System.out.println(Arrays.toString(bytes));
try (ZipFile zipFile = new ZipFile(fileName)) {
}
}
public static class CustomFileSystemProvider extends FileSystemProvider {
public CustomFileSystemProvider(FileSystemProvider provider) {
}
@Override
public String getScheme() {
return "file";
}
@Override
public FileSystem newFileSystem(URI uri, Map<String, ?> env) {
return new CustomFileSystem();
}
@Override
public FileSystem getFileSystem(URI uri) {
return new CustomFileSystem();
}
@Override
public Path getPath(URI uri) {
throw new UnsupportedOperationException();
}
@Override
public SeekableByteChannel newByteChannel(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs) {
return new CustomSeekableByteChannel();
}
@Override
public DirectoryStream<Path> newDirectoryStream(Path dir, DirectoryStream.Filter<? super Path> filter) {
throw new UnsupportedOperationException();
}
@Override
public void createDirectory(Path dir, FileAttribute<?>... attrs) {
throw new UnsupportedOperationException();
}
@Override
public void delete(Path path) {
throw new UnsupportedOperationException();
}
@Override
public void copy(Path source, Path target, CopyOption... options) {
throw new UnsupportedOperationException();
}
@Override
public void move(Path source, Path target, CopyOption... options) {
throw new UnsupportedOperationException();
}
@Override
public boolean isSameFile(Path path, Path path2) {
throw new UnsupportedOperationException();
}
@Override
public boolean isHidden(Path path) {
return false;
}
@Override
public FileStore getFileStore(Path path) {
throw new UnsupportedOperationException();
}
@Override
public void checkAccess(Path path, AccessMode... modes) {
throw new UnsupportedOperationException();
}
@Override
public <V extends FileAttributeView> V getFileAttributeView(Path path, Class<V> type, LinkOption... options) {
throw new UnsupportedOperationException();
}
@Override
public <A extends BasicFileAttributes> A readAttributes(Path path, Class<A> type, LinkOption... options) {
return (A) new CustomBasicFileAttributes();
}
@Override
public Map<String, Object> readAttributes(Path path, String attributes, LinkOption... options) {
throw new UnsupportedOperationException();
}
@Override
public void setAttribute(Path path, String attribute, Object value, LinkOption... options) {
throw new UnsupportedOperationException();
}
private class CustomFileSystem extends FileSystem {
@Override
public FileSystemProvider provider() {
return CustomFileSystemProvider.this;
}
@Override
public void close() {
}
@Override
public boolean isOpen() {
return true;
}
@Override
public boolean isReadOnly() {
return false;
}
@Override
public String getSeparator() {
throw new UnsupportedOperationException();
}
@Override
public Iterable<Path> getRootDirectories() {
throw new UnsupportedOperationException();
}
@Override
public Iterable<FileStore> getFileStores() {
throw new UnsupportedOperationException();
}
@Override
public Set<String> supportedFileAttributeViews() {
throw new UnsupportedOperationException();
}
@Override
public Path getPath(String first, String... more) {
return new CustomPath();
}
@Override
public PathMatcher getPathMatcher(String syntaxAndPattern) {
throw new UnsupportedOperationException();
}
@Override
public UserPrincipalLookupService getUserPrincipalLookupService() {
throw new UnsupportedOperationException();
}
@Override
public WatchService newWatchService() throws IOException {
throw new UnsupportedOperationException();
}
private class CustomPath implements Path {
@Override
public FileSystem getFileSystem() {
return CustomFileSystem.this;
}
@Override
public boolean isAbsolute() {
return false;
}
@Override
public Path getRoot() {
throw new UnsupportedOperationException();
}
@Override
public Path getFileName() {
throw new UnsupportedOperationException();
}
@Override
public Path getParent() {
throw new UnsupportedOperationException();
}
@Override
public int getNameCount() {
throw new UnsupportedOperationException();
}
@Override
public Path getName(int index) {
throw new UnsupportedOperationException();
}
@Override
public Path subpath(int beginIndex, int endIndex) {
throw new UnsupportedOperationException();
}
@Override
public boolean startsWith(Path other) {
throw new UnsupportedOperationException();
}
@Override
public boolean endsWith(Path other) {
throw new UnsupportedOperationException();
}
@Override
public Path normalize() {
throw new UnsupportedOperationException();
}
@Override
public Path resolve(Path other) {
throw new UnsupportedOperationException();
}
@Override
public Path relativize(Path other) {
throw new UnsupportedOperationException();
}
@Override
public URI toUri() {
throw new UnsupportedOperationException();
}
@Override
public Path toAbsolutePath() {
throw new UnsupportedOperationException();
}
@Override
public Path toRealPath(LinkOption... options) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public WatchKey register(WatchService watcher, WatchEvent.Kind<?>[] events, WatchEvent.Modifier... modifiers) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public int compareTo(Path other) {
throw new UnsupportedOperationException();
}
}
}
private class CustomBasicFileAttributes implements BasicFileAttributes {
@Override
public FileTime lastModifiedTime() {
return FileTime.fromMillis(0);
}
@Override
public FileTime lastAccessTime() {
return FileTime.fromMillis(0);
}
@Override
public FileTime creationTime() {
return FileTime.fromMillis(0);
}
@Override
public boolean isRegularFile() {
return true;
}
@Override
public boolean isDirectory() {
return false;
}
@Override
public boolean isSymbolicLink() {
return false;
}
@Override
public boolean isOther() {
return false;
}
@Override
public long size() {
return 2;
}
@Override
public Object fileKey() {
throw new UnsupportedOperationException();
}
}
private class CustomSeekableByteChannel implements SeekableByteChannel {
private boolean written = false;
@Override
public int read(ByteBuffer dst) {
if (this.written) {
return 0;
}
this.written = true;
dst.put((byte) 13);
dst.put((byte) 37);
return 2;
}
@Override
public int write(ByteBuffer src) {
throw new UnsupportedOperationException();
}
@Override
public long position() {
throw new UnsupportedOperationException();
}
@Override
public SeekableByteChannel position(long newPosition) {
throw new UnsupportedOperationException();
}
@Override
public long size() throws IOException {
return 2;
}
@Override
public SeekableByteChannel truncate(long size) {
throw new UnsupportedOperationException();
}
@Override
public boolean isOpen() {
return true;
}
@Override
public void close() {
}
}
}
}
---------- END SOURCE ----------
FREQUENCY : always
When providing custom FileSystemProvider the ZipFile uses the system one instead of the custom one. This prevents providing any byte channels for files which deals with zip files.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the program with -Djava.nio.file.spi.DefaultFileSystemProvider=Program$CustomFileSystemProvider
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The program does not fail with java.io.FileNotFoundException: test.zip (The system cannot find the file specified)
ACTUAL -
The program fails with java.io.FileNotFoundException: test.zip (The system cannot find the file specified)
---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.AccessMode;
import java.nio.file.CopyOption;
import java.nio.file.DirectoryStream;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileTime;
import java.nio.file.attribute.UserPrincipalLookupService;
import java.nio.file.spi.FileSystemProvider;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipFile;
public class Program {
public static void main(String[] args) throws IOException {
String fileName = "test.zip";
byte[] bytes = Files.readAllBytes(Path.of(fileName));
System.out.println(Arrays.toString(bytes));
try (ZipFile zipFile = new ZipFile(fileName)) {
}
}
public static class CustomFileSystemProvider extends FileSystemProvider {
public CustomFileSystemProvider(FileSystemProvider provider) {
}
@Override
public String getScheme() {
return "file";
}
@Override
public FileSystem newFileSystem(URI uri, Map<String, ?> env) {
return new CustomFileSystem();
}
@Override
public FileSystem getFileSystem(URI uri) {
return new CustomFileSystem();
}
@Override
public Path getPath(URI uri) {
throw new UnsupportedOperationException();
}
@Override
public SeekableByteChannel newByteChannel(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs) {
return new CustomSeekableByteChannel();
}
@Override
public DirectoryStream<Path> newDirectoryStream(Path dir, DirectoryStream.Filter<? super Path> filter) {
throw new UnsupportedOperationException();
}
@Override
public void createDirectory(Path dir, FileAttribute<?>... attrs) {
throw new UnsupportedOperationException();
}
@Override
public void delete(Path path) {
throw new UnsupportedOperationException();
}
@Override
public void copy(Path source, Path target, CopyOption... options) {
throw new UnsupportedOperationException();
}
@Override
public void move(Path source, Path target, CopyOption... options) {
throw new UnsupportedOperationException();
}
@Override
public boolean isSameFile(Path path, Path path2) {
throw new UnsupportedOperationException();
}
@Override
public boolean isHidden(Path path) {
return false;
}
@Override
public FileStore getFileStore(Path path) {
throw new UnsupportedOperationException();
}
@Override
public void checkAccess(Path path, AccessMode... modes) {
throw new UnsupportedOperationException();
}
@Override
public <V extends FileAttributeView> V getFileAttributeView(Path path, Class<V> type, LinkOption... options) {
throw new UnsupportedOperationException();
}
@Override
public <A extends BasicFileAttributes> A readAttributes(Path path, Class<A> type, LinkOption... options) {
return (A) new CustomBasicFileAttributes();
}
@Override
public Map<String, Object> readAttributes(Path path, String attributes, LinkOption... options) {
throw new UnsupportedOperationException();
}
@Override
public void setAttribute(Path path, String attribute, Object value, LinkOption... options) {
throw new UnsupportedOperationException();
}
private class CustomFileSystem extends FileSystem {
@Override
public FileSystemProvider provider() {
return CustomFileSystemProvider.this;
}
@Override
public void close() {
}
@Override
public boolean isOpen() {
return true;
}
@Override
public boolean isReadOnly() {
return false;
}
@Override
public String getSeparator() {
throw new UnsupportedOperationException();
}
@Override
public Iterable<Path> getRootDirectories() {
throw new UnsupportedOperationException();
}
@Override
public Iterable<FileStore> getFileStores() {
throw new UnsupportedOperationException();
}
@Override
public Set<String> supportedFileAttributeViews() {
throw new UnsupportedOperationException();
}
@Override
public Path getPath(String first, String... more) {
return new CustomPath();
}
@Override
public PathMatcher getPathMatcher(String syntaxAndPattern) {
throw new UnsupportedOperationException();
}
@Override
public UserPrincipalLookupService getUserPrincipalLookupService() {
throw new UnsupportedOperationException();
}
@Override
public WatchService newWatchService() throws IOException {
throw new UnsupportedOperationException();
}
private class CustomPath implements Path {
@Override
public FileSystem getFileSystem() {
return CustomFileSystem.this;
}
@Override
public boolean isAbsolute() {
return false;
}
@Override
public Path getRoot() {
throw new UnsupportedOperationException();
}
@Override
public Path getFileName() {
throw new UnsupportedOperationException();
}
@Override
public Path getParent() {
throw new UnsupportedOperationException();
}
@Override
public int getNameCount() {
throw new UnsupportedOperationException();
}
@Override
public Path getName(int index) {
throw new UnsupportedOperationException();
}
@Override
public Path subpath(int beginIndex, int endIndex) {
throw new UnsupportedOperationException();
}
@Override
public boolean startsWith(Path other) {
throw new UnsupportedOperationException();
}
@Override
public boolean endsWith(Path other) {
throw new UnsupportedOperationException();
}
@Override
public Path normalize() {
throw new UnsupportedOperationException();
}
@Override
public Path resolve(Path other) {
throw new UnsupportedOperationException();
}
@Override
public Path relativize(Path other) {
throw new UnsupportedOperationException();
}
@Override
public URI toUri() {
throw new UnsupportedOperationException();
}
@Override
public Path toAbsolutePath() {
throw new UnsupportedOperationException();
}
@Override
public Path toRealPath(LinkOption... options) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public WatchKey register(WatchService watcher, WatchEvent.Kind<?>[] events, WatchEvent.Modifier... modifiers) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public int compareTo(Path other) {
throw new UnsupportedOperationException();
}
}
}
private class CustomBasicFileAttributes implements BasicFileAttributes {
@Override
public FileTime lastModifiedTime() {
return FileTime.fromMillis(0);
}
@Override
public FileTime lastAccessTime() {
return FileTime.fromMillis(0);
}
@Override
public FileTime creationTime() {
return FileTime.fromMillis(0);
}
@Override
public boolean isRegularFile() {
return true;
}
@Override
public boolean isDirectory() {
return false;
}
@Override
public boolean isSymbolicLink() {
return false;
}
@Override
public boolean isOther() {
return false;
}
@Override
public long size() {
return 2;
}
@Override
public Object fileKey() {
throw new UnsupportedOperationException();
}
}
private class CustomSeekableByteChannel implements SeekableByteChannel {
private boolean written = false;
@Override
public int read(ByteBuffer dst) {
if (this.written) {
return 0;
}
this.written = true;
dst.put((byte) 13);
dst.put((byte) 37);
return 2;
}
@Override
public int write(ByteBuffer src) {
throw new UnsupportedOperationException();
}
@Override
public long position() {
throw new UnsupportedOperationException();
}
@Override
public SeekableByteChannel position(long newPosition) {
throw new UnsupportedOperationException();
}
@Override
public long size() throws IOException {
return 2;
}
@Override
public SeekableByteChannel truncate(long size) {
throw new UnsupportedOperationException();
}
@Override
public boolean isOpen() {
return true;
}
@Override
public void close() {
}
}
}
}
---------- END SOURCE ----------
FREQUENCY : always