File Last Modified Not Updating when Java Writes to Windows Server 2016
Asked Answered
T

1

9

I have a Java 10 application on Windows Server 2016 which is continually writing to a file using java.util.logging. In Windows File Explorer, the "Last modified" and "Size" columns do not update. Pressing [F5] does not update the details. DOS DIR gives the same incorrect answer. Right Click > Properties > Details gives an even different (and older) answer.

Only running DOS TYPE or opening/closing (without save) in Notepad on the file, seems to cause File Explorer and DOS DIR to update.

I assume the Java code is correct with respect to flush() as the same classes on Java 8 on Windows Server 2008 causes File Explorer to update. Also when running TYPE and Notepad I also see the timestamped records matching the system clock, but well after "Last Modified".

So I assume that there is something up with Windows Server 2016. Any ideas what to check?

Telecast answered 31/7, 2018 at 10:59 Comment(5)
Does the application running on Java 8 work on Windows Server 2016? Does the application running on Java 10 work on Windows Server 2008? If I'm not mistaken, you need to configure one of these tests in order to identify whether the issue is introduced by the newer version of Java or the newer version of Windows Server.Mercantilism
Same class using Java 8 on 2016 also has the same symptoms. Control M also has the same symptoms (I may be wrong, but although Control M is an EXE, it looks as if it is running Java 8 using Apache commons logging under the covers). Native binaries (e.g. DLLs) do not seem to exhibit this problem.Telecast
Are the files on a local disk or a network file share / file system of some kind? I suspect that you are seeing some kind of network related file metadata issue. Not actually Java's doing.Neese
Local disks, with nobody else logged on to the server. However, the server and it's disk are on VMWare. I came across this issue JDK-8170718 which says it may have something to do with file extensions. Currently I am using .log. When I get back to work tomorrow I will try the more common .txt and see what happens.Telecast
With respect to JDK-8170718, changing to .txt did not make a difference.Telecast
G
5

So I assume that there is something up with Windows Server 2016. Any ideas what to check?

By default Windows is setup to work this way. From File timestamp not updating on 2008 but does on 2003:

On 2003, opening the log file folder in explorer, you can see the timestamp and files size change before your eyes each time the log is updated.

On 2008, most of the time, there is no change unless you interact in some other way...

[snip]

Yes, some of these attributes have been disabled in 2008. If you want for example want to see/use “Last Accessed” time you need to enable the tracking of this attribute.

You can enable this by setting HKLM\System\CurrentControlSet\Control\FileSystem\NtfsDisableLastAccessUpdate to 0 (this value is REG_DWORD).

Please beware that his could impact disk IO performance on busy file servers !

So the behavior was change to improve performance.

From the Performance Tuning Web Servers:

The system-global switch NtfsDisableLastAccessUpdate (REG_DWORD) 1 is located under HKLM\System\CurrentControlSet\Control\FileSystem and is set by default to 1. This switch reduces disk I/O load and latencies by disabling date and time stamp updating for the last file or directory access. Clean installations of Windows Server 2016, Windows Server 2012 R2, Windows Server 2012, Windows Server 2008 R2, and Windows Server 2008 enable this setting by default, and you do not need to adjust it. Earlier versions of Windows did not set this key. If your server is running an earlier version of Windows, or it was upgraded to Windows Server 2016, Windows Server 2012 R2, Windows Server 2012, Windows Server 2008 R2, or Windows Server 2008, you should enable this setting.

It appears that this setting can still be used in Windows Server 2016.

I assume the Java code is correct with respect to flush() as the same classes on Java 8 on Windows Server 2008 causes File Explorer to update. Also when running TYPE and Notepad I also see the timestamped records matching the system clock, but well after "Last Modified".

Flush is not the same as sync. The FileHandler just performs a flush after each record is published. Windows is not setup to force a writing of the metadata to the file system. From File “Date modified” property are not updating while modifying a file without closing it.:

On 2008, "Last Modified" field on log files is not updated unless another program attempts to open the file or the utility is stopped, even if F5 is pressed to refresh the view.

Explorer gets is information from NTFS, by using a cmd prompt and "dir" we found that the NTFS metadata for the files is not updated until the handle to a file is closed.

Refreshing the information of a FOLDER is just going to go to the (memory resident) metadata cached by NTFS, but querying the file explicitly will force disk I/O to get the properties - this was a design change introduced in Vista to reduce unnecessary disk I/O to improve performance

There are some exceptions to this rule:

  • in some, but not all, cases a simple "dir filename" is enough to refresh the metadata
  • "special" folders may be treated differently, such as user profiles where we do not expect a large number of files and want to be able to rely on the file data presented
  • kernel filter drivers may change the behaviour as by design they "add, remove or change functionality of other drivers"

As the workaround is for any process to open and close a handle to the log files, a tool was written to do exactly that, plus get the file information, using the following APIs:

  • CreateFile
  • GetFileInformationByHandle
  • CloseHandle

You might be able to attempt to open a FileInputStream using the file name that the FileHandler created.

Only running DOS TYPE or opening/closing (without save) in Notepad on the file, seems to cause File Explorer and DOS DIR to update.

The only universal method I've found for updating the metadata from an outside process is to select a file using the file explorer interactively:

explorer /select, c:\test\file.txt

Most likely this is very similar to what is happening in notepad.

I like your use of TYPE command. You can use that with the nul to ignore the output.

type filename.log > NUL

It is possible that running dir with metadata switches might force the update of metadata:

dir /A /R /Q filename.log > nul
Gospel answered 31/7, 2018 at 16:9 Comment(2)
thanks for taking the time to check. I also stumbled upon these posts. The regy change doesn't work, as the comments on the original threads confirm. In my Java, if I get the FileDescriptor and call sync() (as you suggest) it does cause "Date modified" to update (even without having to [F5]). I implemented a TimerTask to sync() every minute, because I am not too concerned of accuracy down to the second. However this fixes my Java, but doesn't fix anything I cannot re-code. I will up vote your answer, but not mark it as a solution as it seems to be a >= WS2008R2 issue.Telecast
@lafaul Selecting a file in windows explorer was the only true method that seemed to work for me. I personally could never get that to work right in an automated way.Gospel

© 2022 - 2024 — McMap. All rights reserved.