JDK-7127235 : (fs) NPE in Files.walkFileTree if cached attributes are GC'ed
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_7
  • CPU: x86
  • Submitted: 2012-01-05
  • Updated: 2012-06-18
  • Resolved: 2012-06-11
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 7 JDK 8
7u6Fixed 8 b23Fixed
Description
FULL PRODUCT VERSION :
java version "1.7.0_01"
Java(TM) SE Runtime Environment (build 1.7.0_01-b08)
Java HotSpot(TM) 64-Bit Server VM (build 21.1-b02, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Any version of Windows 32 or 64 bits since Server 2003 (did not test on older versions)

EXTRA RELEVANT SYSTEM CONFIGURATION :
NTFS filesystem
Seems to happen more frequently when shadow volumes are used

A DESCRIPTION OF THE PROBLEM :
In java.nio.file.FileTreeWalker line 83:

private FileVisitResult walk(Path file, int depth, List<AncestorDirectory> ancestors)
        throws IOException
    {
        // if attributes are cached then use them if possible
        BasicFileAttributes attrs = null;
        if ((depth > 0) &&
            (file instanceof BasicFileAttributesHolder) &&
            (System.getSecurityManager() == null))
        {
            BasicFileAttributes cached = ((BasicFileAttributesHolder)file).get();
            if (!followLinks || !cached.isSymbolicLink())
                attrs = cached;
        }
       ...


The optimization that tries to reuse the cached attributes sometimes gets null attributes, that is ((BasicFileAttributesHolder)file).get() returns null so that cached is null. As the next test checks is cached.isSymbolicLink without checking first if it is not null, the code generates a NPE.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use a FileTreeWalker starting from C:\ (having an antivirus scanner or other concurrent programs accessing the filesystem concurrently might help trigger the bug)
Most often got a stack trace with a depth of 5:
java.lang.NullPointerException
 at java.nio.file.FileTreeWalker.walk(Unknown Source)
 at java.nio.file.FileTreeWalker.walk(Unknown Source)
 at java.nio.file.FileTreeWalker.walk(Unknown Source)
 at java.nio.file.FileTreeWalker.walk(Unknown Source)
 at java.nio.file.FileTreeWalker.walk(Unknown Source)
 at java.nio.file.Files.walkFileTree(Unknown Source)

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Walking directories without errors
ACTUAL -
java.lang.NullPointerException
 at java.nio.file.FileTreeWalker.walk(Unknown Source)
 at java.nio.file.FileTreeWalker.walk(Unknown Source)
 at java.nio.file.FileTreeWalker.walk(Unknown Source)
 at java.nio.file.FileTreeWalker.walk(Unknown Source)
 at java.nio.file.FileTreeWalker.walk(Unknown Source)
 at java.nio.file.Files.walkFileTree(Unknown Source)

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.NullPointerException
 at java.nio.file.FileTreeWalker.walk(Unknown Source)
 at java.nio.file.FileTreeWalker.walk(Unknown Source)
 at java.nio.file.FileTreeWalker.walk(Unknown Source)
 at java.nio.file.FileTreeWalker.walk(Unknown Source)
 at java.nio.file.FileTreeWalker.walk(Unknown Source)
 at java.nio.file.Files.walkFileTree(Unknown Source)

REPRODUCIBILITY :
This bug can be reproduced often.

---------- BEGIN SOURCE ----------
Any use of FileTreeWalker should do
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
No workaround. Duplicate the code of FileTreeWalker to write your own and test for null cached attributes.

Comments
EVALUATION An oversight in the original implementation, easily fixed.
05-01-2012