JDK 10 RFR of 8180767: A return value of zero from java.io.File#lastModified() is ambiguous

Stuart Marks stuart.marks at oracle.com
Mon May 22 23:15:25 UTC 2017

On 5/22/17 1:45 PM, Brian Burkhalter wrote:
> On May 22, 2017, at 1:42 PM, Martin Buchholz <martinrb at google.com> wrote:
>> I have no opinion on how to address the problem - just pointing out that the problem is real.
>> I might choose an even less likely value than 1 if I were to switch from 0.
> Perhaps Long.MAX_VALUE.

I agree with Martin that this is a real problem.

I'm pretty sure I've seen files with a timestamp of zero. I can't remember the 
exact circumstances, but it was something like a tar file that was converted 
from a dump of some foreign filesystem where they either didn't bother to 
convert the timestamps, or that didn't have timestamps at all. Whoever wrote the 
converter had to choose some value to fill in; they chose zero. When tar 
extracts the files, it sets the modification time to the time value found in the 
archive. This resulted in a bunch of files with a modification date of the epoch.

Thus, I believe the files with a modification time of zero (the epoch) are 
rather more common than one might think.

Now this turns into a problem for the File.lastModified, as a return value of 0L 
can't distinguish between success on a file whose modified timestamp was the 
epoch, and file-not-found or another IOException. This is unfortunate, but I 
think we just have to live with it. Returning 1L instead of 0L seems like a bad 
idea, as the API is actually lying about the value it retrieved from the file 
system. I can imagine that this would lead to all sorts of subtle errors. For 
example, suppose somebody were to have written a "jtar" command that attempts to 
be a Java equivalent of the Unix "tar" command, and it uses File.lastModified. 
Using "tar" to extract an archive containing files with zero timestamps, then 
using "jtar" to create an archive from the extracted files, would result in an 
archive that differs from the original "tar" archive, and indeed one that 
differs from one produced by "jtar" on an earlier JDK release.

So yes, I'd say that returning 1L (or any other value) instead of 0L would be an 
incompatible change.

The specification for File.lastModified already has this note:

> Where it is required to distinguish an I/O exception from the case where 0L
> is returned, or where several attributes of the same file are required at the
> same time, or where the time of last access or the creation time are
> required, then the Files.readAttributes method may be used.

I think this is sufficient. People who care about this case will have to rewrite 
their code using Files.readAttributes instead of File.lastModified.


More information about the core-libs-dev mailing list