In the ResourceManager class,
resource.process()
was always (twice) called before the function call
resourceLoader.getLastModified( resource )
that gets the resource timestamp.
The problem is that if (with loads of bad luck) the
resource is updated between these too calls, the old
resource version data would be associated with the
newer version timestamp.
The consequence is that the subsequent timestamp
checks on the resource would give it has not changed.
These patch is not ideal but it is what is possible
with the current architecture (*). It simply consists
in an order change - getting the timestamp before
loading the resource.
Its worse case is that a new version of the resource,
changed (again) between the 2 calls will be loaded
twice - because of the new version data being
associated with the old timestamp.
However, this just results in redundant work on the
very-bad-Murphy-at-work case instead of deficient
functionality (e.g.: an updated template not being
reloaded).
As mentioned before, be aware that text newline
sequences might be wrong for Linux (I'm not sure).
And I am sure it will need some editing to work.
Can some one fix it and apply it?
Thanks and have fun,
Paulo Gaspar
(*) - Anyway, I think it is impossible to read the
contents of a file and its timestamp in a
single step. So, the most frequent case of
the file would always have this limitation,
unlike database stored resources.
jakarta-velocity/src/java/org/apache/velocity/runtime/resource/ResourceManager.java
--- ResourceManager.java
+++ ResourceManager.java
@@ -260,6 +260,12 @@
try
{
/*
+ * read how old the resource is _before_
+ * processing (=>reading) it
+ */
+ long howOldItWas = resourceLoader.getLastModified( resource );
+
+ /*
* read in the fresh stream and parse
*/
@@ -270,8 +276,7 @@
* the modification check counters
*/
- resource.setLastModified(
- resourceLoader.getLastModified( resource ));
+ resource.setLastModified( howOldItWas );
}
catch( ResourceNotFoundException rnfe )
{
@@ -314,6 +319,7 @@
//! Bug this is being run more then once!
+ long howOldItWas = 0; // Initialize to avoid warnings
for (int i = 0; i < resourceLoaders.size(); i++)
{
resourceLoader = (ResourceLoader) resourceLoaders.get(i);
@@ -322,6 +328,11 @@
Runtime.info("Attempting to find " + resourceName +
" with " + resourceLoader.getClassName());
+ /*
+ * read how old the resource is _before_
+ * processing (=>reading) it
+ */
+ howOldItWas = resourceLoader.getLastModified( resource );
if (resource.process())
break;
}
@@ -332,7 +343,7 @@
if (resource.getData() == null)
throw new ResourceNotFoundException("Can't find " + resourceName
+ "!");
- resource.setLastModified(resourceLoader.getLastModified(resource));
+ resource.setLastModified(howOldItWas);
resource.setModificationCheckInterval(
resourceLoader.getModificationCheckInterval());