Community
Participate
Working Groups
At the top of the org.eclipse.jdt.core.prefs file in .settings, there is a line with a date stamp (#Thu Aug 18 15:28:50 BST 2005), which seems to get updated when no changes have been made to the settings. We are using .settings extensively, and this is causing us problems, as we are ending up with conflicts, because this timestamp is getting updated when there are no changes to the actual content of the file, only to the timestamp. Is the timestamp necessary, and if so, could it please be only updated on real changes to the file.
This bug is still really annoying me, and continues into the 3.1.1 build. Can you at least justify the existence of that date stamp? If not, I suggest removing the date stamp.
JDT/Core preferences rely on Platform Resources preferences and so I do not know whether this time stamp is used or not. I'm currently tracking whether it's JDT/Core or Platform Resources which is responsible of this unnecessary update... DJ, if you have any hits on this subject please let me know, thx
I will check to ensure project prefs are behaving correctly w.r.t. isDirty and saving.
Seem to be a Platform preferences issue... Not easy to reproduce. My scenario is to import in my workspace a project checked out in another workspace and not modified. Before, I put a breakpoint on last line of ProjectPreferences.read(ProjectPreferences node, IFile file). For 3.2 M4 it's at line 394: Platform.getPreferencesService().applyPreferences(myNode); When this bkpt is reached, toggle a watchpoint on EclipsePreferences.dirty field and you'll see while executing this last line that preferences are written although it should not... I also verified all JDT/Core preferences possible update during this import and everything is clean (ie. no unnecessarily update is performed) HTH
Thanks for the investigation Frederic.
*** Bug 143770 has been marked as a duplicate of this bug. ***
Glad to see this has been assigned. There's another related scenario that has the same theme, that of XML config files (e.g. .project and .classpath) where the same information is output in a different order, therefore making it impossible to know what the change is that is being committed. From a developers point of view, it's an annoyance in the same way as for .settings, as it looks like a change happened, but didn't, but makes changes difficult to spot. Perhaps we need the "Compare files" to do so, not as text files, but as XML structure.
Created attachment 159764 [details] Relevant stack-traces when reproducing the issue The issue can be reproduced in the debugger (using 3.6M4): 1) Set a breakpoint at the beginning of the RefreshJob.runInWorkspace(...) 2) Import a java-project with a file '.settings/org.eclipse.jdt.core.prefs' --> The java indexer is notified about the new project and accesses the project preferences. The preference node is created, an attempt to load them from file is made, however the file does not yet exist, so the node remains to be empty. 3) After that let the refresh job continue --> When the file '.settings/org.eclipse.jdt.core.prefs' is refreshed, the existing empty project preference node is updated and marked as dirty. It is not yet flushed to disk at this point (because flag isLoading is set). Note: If the project preference node does not yet exist at this point, it is created and loaded and updated. Then the update does not actually change anything, so the node is not set dirty and we are fine) 4) Any operation that flushes the preference tree now causes the dirty node to be flushed to disk. E.g. a preference import will trigger that.
Created attachment 159920 [details] Clears the dirty flag after updating project prefs from file The patch fixes the issue by clearing the dirty flag after applying the preferences as read from the file. The preference node may actually be modified through listeners at this point. Up to now, such changes were sometimes flushed to disk accidentially (when some other client flushed the entire preferece tree), but usually they were not persisted. With the patch such modifications will not be flushed, unless at a later point the node is further modified and flushed afterwards.
Is it also possible to suppress the date stamp in the preference file? Most (all?) filesystems already have a modified time, so putting it in the prefs file seems overkill.
(In reply to comment #10) > Is it also possible to suppress the date stamp in the preference file? Most > (all?) filesystems already have a modified time, so putting it in the prefs > file seems overkill. That's a different issue and there is no trivial fix for that, the timestamp is written by java.util.Properties.store(..), which is used to persist the project preferences.
Also, note that with Markus' fix, the timestamp in the properties file will change much less frequently so I do not think that this will be an issue any more. And I do see some value in the timestamp since when you unpersist the project out of an archive, CM Repository, ... the timestamp on disk may be different than when the properties file was actually written.
(In reply to comment #12) Yep, point taken. Markus' fix will make a big difference to the project deltas we see when using Eclipse with CCRC.
Created attachment 159954 [details] Patch with slightly updated comments I slightly updated comments to reflect my understanding of what the patch does. Markus: Would it make sense to compare the prefs-on-disk versus prefs-in-memory before resetting the dirty flag? I see that in the read() method, we already have the "original" prefs from file as well as the "merged/imported" ones, so this should be possible: //if the node existed before importing, it is marked dirty although unchanged if(node.isDirty() && comparePrefs(myNode, node)==0) { //reset dirty flag since prefs were not really modified node.setDirty(false) }
(In reply to comment #14) > ... > //if the node existed before importing, it is marked dirty although unchanged > if(node.isDirty() && comparePrefs(myNode, node)==0) { > //reset dirty flag since prefs were not really modified > node.setDirty(false) > } I think the intended behavior is not to flush such changes. (The initial modifications to the preferences via a PreferenceModifyListener will be done every time the project is opened. So there is no actual need to flush them.) Even if you leave the dirty-flag set, the flushing will be suppressed. It's only done sometimes by accident. For example when you use the import wizard to import some workspace preferences this will as a side effect flush all dirty project preferences.
I have committed the fix to HEAD (all AutomatedTests pass). The important thing to understand here is that this fix does not protect us from race conditions, but it does make the effect of race conditions deterministic. If a client is in the middle of updating project prefs when a refresh monitor forces re-loading preferences from disk, we get a version conflict which we cannot resolve: the content from disk overrides the content in memory, both before the fix and after. Before the fix, the preference node remained dirty thus indicating ("needs saving") and it was purely random who would ever perform a save on the next preference flush. With the fix, after loading content from file, the in-memory representation correctly specifies the prefs node as unchanged compared to the disk, so no flush is needed, so we get the deterministic behavior of "file system is always king" and avoid the scenario where an unflushed prefs node remains hanging around forever. So the fix definitely improves the situation, especially in the case of listeners modifying project prefs too early after project open, when prefs are not yet correctly initialized. In order to avoid race conditions, some more work would be needed elsewhere: - delay "project open" notification until after project prefs have been initialized - Ensure that project prefs cannot be refreshed from disk while a client is editing them I think that the 2nd case is mostly ensured today already, by flushing modified prefs immediately. In case the resource is out of sync while flushing, the flush runs into an error, so users are aware of potential problems. Thanks Markus for all the investigations, this was a great bug to fix.