[
https://issues.apache.org/jira/browse/TILES-503?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Jeff Reichenberg reopened TILES-503:
------------------------------------
I've created a test case that illustrates the issue. My only customization is
the extension of ResolvingLocaleUrlDefinitionDAO, which just adds some console
logging at key points.
Here are the steps. tiles-503.zip file attached to the bug report. Looking
forward to your comments.
1. Unzip the tiles-503.zip, cd into the "tiles-503" dir and run "mvn tomcat:run"
2. Hit http://localhost:8080/tiles-503/index.jsp with default "Accept-Language"
header, "en-us" in my case. Tiles builds the definitions for this locale and
"parent" locales
INFO: Starting Coyote HTTP/1.1 on http-8080
Post-processed 2 definitions for locale ''.
Post-processed 2 definitions for locale 'English'.
Post-processed 2 definitions for locale 'English (United States)'.
3. Update the "version" attribute in src/main/webapp/WEB-INF/tiles.xml to 2:
<put-attribute name="version" value="2" />. Save the file
4. Start a new browser process/clear session cookies. Hit
http://localhost:8080/tiles-503/index.jsp with "Accept-Language" header changed
to, "fr-fr". (You can use Charles proxy rewrite function to do this, or
Fiddler). Tiles builds the definitions for "fr-fr" and "parent" locales using
the updated Tile definitions (i.e. "version 2"). The update is shown on the
index.jsp page. Make sure the "Accept-Language header" text on the web page
reads "fr-fr".
Post-processed 2 definitions for locale ''.
Post-processed 2 definitions for locale 'French'.
Post-processed 2 definitions for locale 'French (France)'.
5. Turn off header rewriting and start a new browser process/clear session
cookies.
6. Hit http://localhost:8080/tiles-503/index.jsp. The original "version"
attribute value is shown on the index.jsp as expected because we haven't
refreshed the tile definitions yet and the default locale still has the old
definitions in memory. Now click the "refresh tile definitions" link on the
index.jsp page. This calls refresh() on the container. Note the following
output. We'd expect to see the "Post-refresh size of locale2definitionMap" to
be 0 because we updated a definition and it should be cleared out.
Pre-refresh size of locale2definitionMap: 5
Checking if refresh required, last mod dates for Tile def XMLs follow...
Last mod date for XML jndi:/localhost/tiles-503/WEB-INF/tiles_fr.xml: 0, cached
last mod date: 0.
Last mod date for XML jndi:/localhost/tiles-503/WEB-INF/tiles_fr_FR.xml: 0,
cached last mod date: 0.
Last mod date for XML jndi:/localhost/tiles-503/WEB-INF/tiles_en.xml: 0, cached
last mod date: 0.
Last mod date for XML jndi:/localhost/tiles-503/WEB-INF/tiles_en_US.xml: 0,
cached last mod date: 0.
Last mod date for XML jndi:/localhost/tiles-503/WEB-INF/tiles.xml:
1271188631745, cached last mod date: 1271188631745.
Post-refresh size of locale2definitionMap: 5
Completed Tiles refresh attempt for webapp
org.apache.catalina.core.applicationcontextfac...@15fd251
7. Go back to http://localhost:8080/tiles-503/index.jsp. We'd expect to see
the updated "version" attribute. We don't, we still see "1". This is because
the "fr-fr" locale request came in between the time we updated our definition
xml on the file system and the time we called refresh() on the container. This
"corrupted" the global BaseLocaleUrlDefinitionDAO#lastModifiedDates Map.
Because the Map is global, but only the "fr-fr" locale was rebuilt, no other
locales will ever be refreshed until the server is restarted or another update
is made to the XML and we race to run refresh() before a request from an
unbuilt locale comes in.
> XML definitions for top/default locale can be reloaded without invalidating
> definition maps for locales that share the same definitions
> ---------------------------------------------------------------------------------------------------------------------------------------
>
> Key: TILES-503
> URL: https://issues.apache.org/jira/browse/TILES-503
> Project: Tiles
> Issue Type: Bug
> Components: tiles-core
> Affects Versions: 2.0.0, 2.0.1, 2.0.2, 2.0.3, 2.0.4, 2.0.5, 2.0.6, 2.0.7,
> 2.1.0, 2.1.1, 2.1.2, 2.1.3, 2.1.4, 2.2.0, 2.2.1
> Reporter: Jeff Reichenberg
> Assignee: Antonio Petrelli
> Attachments: tiles-503.zip
>
> Original Estimate: 0h
> Remaining Estimate: 0h
>
> CachingLocaleUrlDefinitionDAO#refreshRequired() can incorrectly return false
> in certain circumstances, causing refresh to not update Tile definitions even
> though one or more underlying definition XML files have been updated on the
> file system since startup/last refresh.
> Tiles stores an in-memory cache of Tile definitions keyed by locale. These
> definitions are built lazily as requests come in, based on the locale of the
> request. If the locale on the request doesn't yet have definitions
> associated with it, definitions are built for that locale (and parent
> locales) on-the-fly and cached. If the lazy building of definitions for a
> new locale results in an updated XML file loaded from the file system that is
> shared by an existing locale, the definitions already cached for other
> locales that share the same definition file should be invalidated.
> Use Case:
> * Updated Tile definition XML files are pushed onto servers. The servers
> continue to field requests.
> * A request with a previously unseen locale comes in, causing a set of
> definitions to be built for that locale and parent locales. The updated XMLs
> are processed from the file system for the new locale only, which updates the
> global cache of XML file last modified dates
> (BaseLocaleUrlDefinitionDAO#lastModifiedDates)
> * BaseLocaleUrlDefinitionDAO#refreshRequired() compares file system last
> modified dates to the cached ones and returns true if they differ. Since the
> global cache of last modified dates was updated in the previous step, the
> framework doesn't detect that anything has changed. Thus, it still holds
> out-dated definitions for all locales other than new ones that come in after
> the XML file push.
> I don't have test case, unfortunately, but my steps to reproduce using a
> Servlet environment and ResolvingLocaleUrlDefinitionDAO are:
> * Use a Tile definition XML files with no locale suffix, e.g.
> "my-base-tile-defs.xml"
> * Issue a request with the "Accept-Language" HTTP header "en-us". Tile
> definitions are built for locales "en-us", "en" and "" all using the same
> base XML file
> * Update one of the tile definitions in the XML, save to the file system
> * Issue a request with the "Accept-Language" HTTP header "fr-fr". Tile
> definitions are built for locales "fr-fr", "fr" and rebuilt for "" all using
> the updated XML file. Cached definitions for "en-us" and "en" are not
> invalidated, even though the underlying XML file used to build both of them
> are now changed. This is because
> BaseLocaleUrlDefinitionDAO#lastModifiedDates now has the updated last mod
> date found when the definitions were built for "fr-fr", even though the
> updated definitions are not reflected in the definitions for "en-us"
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
https://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira