JDK-8153250 : java.io.File does not handle Windows paths of the form "D:" (no path) correctly
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 8,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2016-03-25
  • Updated: 2020-07-15
  • Resolved: 2017-01-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b153Fixed
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_74"
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Windows 7 x64 SP1

A DESCRIPTION OF THE PROBLEM :
The code 

    File f = new File("D:");

returns a File object reflecting the current working directory on the specified drive. Doing f.listFiles() on that object returns an array of File objects reflecting files in the current directory.  However, attempting to use those File objects to access the files themselves fails.  

See the code sample and output below

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The following code was run in Eclipse while the current directory of the D drive was D:\dev\src\pdxep

public class Foo3
{
    public static void main(String[] args)  throws Exception
    {
        File f = new File("D:");
        System.out.println(f.getCanonicalPath());
        for (File x : f.listFiles())
            System.out.println(x + " " + x.getCanonicalPath() + " " + x.getAbsolutePath() + " " + x.exists() + " " + x.getAbsoluteFile().exists());
    }
}

See also http://stackoverflow.com/q/36212863/18157

ACTUAL -
D:\dev\src\pdxep
D:\.classpath D:\dev\src\pdxep\.classpath D:\dev\src\pdxep\.classpath false true
D:\.project D:\dev\src\pdxep\.project D:\dev\src\pdxep\.project false true
D:\.settings D:\dev\src\pdxep\.settings D:\dev\src\pdxep\.settings false true
D:\gallery D:\dev\src\pdxep\gallery D:\dev\src\pdxep\gallery false true
D:\pom.xml D:\dev\src\pdxep\pom.xml D:\dev\src\pdxep\pom.xml false true
D:\src D:\dev\src\pdxep\src D:\dev\src\pdxep\src false true
D:\target D:\dev\src\pdxep\target D:\dev\src\pdxep\target false true

Note that toString() on the returned files omits the current directory getCanonicalPath() and getAbsolutePath() both return the correct value, but , exists() returns false when it should return true.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
See above
---------- END SOURCE ----------


Comments
I don't see why the bug needs manual verification when a test was added that covers it. Please refer to the changeset.
20-01-2017

Review thread: http://mail.openjdk.java.net/pipermail/core-libs-dev/2017-January/045817.html
10-01-2017

It does indeed look as if there is a problem here in handling directory-relative paths correctly. These types of paths are discussed in [1] where this description is given: "If a file name begins with only a disk designator but not the backslash after the colon, it is interpreted as a relative path to the current directory on the drive with the specified letter. Note that the current directory may or may not be the root directory depending on what it was set to during the most recent "change directory" operation on that disk. [...] [T]he system keeps track of the current drive along with the current directory of that drive, it also keeps track of the current directories in each of the different drive letters [...], regardless of which drive designator is set as the current drive." Note that this situation is handled correctly by the equivalent java.nio code: Path path = Paths.get("D:"); Stream<Path> s = Files.list(path); s.forEach(p -> {System.out.printf("%s -> %s%n", p, Files.exists(p));}); [1] https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
06-01-2017

Attached test case executed on : JDK 8 - fail JDK 8u77 - Fail JDK 9 - Fail When using D: , the file class represents current working directory, whereas when using D:\\ , the file class represents the directory under D drive. This results in .exists() returning false for the files retrieved when using D: .
01-04-2016