-
Bug
-
Resolution: Fixed
-
P4
-
8, 11, 16, 17
-
b18
-
x86_64
-
windows_10
-
Not verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8287911 | 11.0.17-oracle | Weibing Xiao | P4 | Resolved | Fixed | b01 |
JDK-8288873 | 11.0.17 | Goetz Lindenmaier | P4 | Resolved | Fixed | b01 |
JDK-8294854 | 8u361 | Weibing Xiao | P4 | Resolved | Fixed | b02 |
Windows 10.
Tested using two different Java installations:
java -version yields:
java version "16" 2021-03-16, Java(TM) SE Runtime Environment (build 16+36-2231)
java -version yields:
openjdk version "11.0.2" 2019-01-15 OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
A DESCRIPTION OF THE PROBLEM :
Windows file system roots are commonly identified by a letter and a colon.
The letter is case insensitive, e.g. c: and C: denote the same root.
The WindowsFileStore uses the root name to check for equality and compute a hashCode, which makes sense. However, it does so with case sensitivity. The equality of two different WindowsFileStore object therefore depends on how it was acquired.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Acquire two FileStore objects representing the same actual file store, but use paths with different case.
Compare them using equals().
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
FileStore objects representing the same actual file store should be equal, and return the same hashCode.
ACTUAL -
FileStore objects representing the same actual file store may or may not be equal, depending on how the FileStore object was acquired.
If equality is not supposed to work in this way (it's not documented), there should be a different official means of determining if two different FileStore objects represent the same underlying file store.
---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.nio.file.*;
public class Repro {
public static void main(String[] args) throws IOException {
final FileSystem fs = FileSystems.getDefault();
final FileStore upper = Files.getFileStore(fs.getPath("C:\\"));
final FileStore lower = Files.getFileStore(fs.getPath("c:\\"));
System.out.println(lower.equals(upper)); // false
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
- Convert the path to a given case before acquiring it. (I have not investigated how this inter-works with FileSystem.getFileStores().) I don't know if this is a good workaround for other platforms.
- Use toString() to check for equality. This does not work on Windows if the user sets or changes the volume's label. I don't know if it works on other platforms.
- It may work to get the volume:vsn attribute, and use that for comparison. I bet that won't work for other platforms.
FREQUENCY : always
- backported by
-
JDK-8287911 (fs) WindowsFileStore equality depends on how the FileStore was constructed
- Resolved
-
JDK-8288873 (fs) WindowsFileStore equality depends on how the FileStore was constructed
- Resolved
-
JDK-8294854 (fs) WindowsFileStore equality depends on how the FileStore was constructed
- Resolved
- duplicates
-
JDK-8219644 java/nio/file/Files/CopyAndMove.java: Test threw exception: java.lang.RuntimeException: AtomicMoveNotSupportedException expected
- Closed
- relates to
-
JDK-8265100 (fs) WindowsFileStore.hashCode() should read cached hash code once
- Resolved
- links to
-
Commit openjdk/jdk11u-dev/97a472ce
-
Commit openjdk/jdk/cc54de76
-
Review openjdk/jdk11u-dev/1137
-
Review openjdk/jdk/3279