[ 
https://issues.apache.org/jira/browse/TILES-513?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Antonio Petrelli updated TILES-513:
-----------------------------------

     Original Estimate: 0h
    Remaining Estimate: 0h

Fixed by putting the definition map only for the selected locale.
Postponed inheritance resolution, storing definition patterns at the end of the 
definitions loading for the needed locale.
Un-deprecated a method in CachingLocaleUrlDefinitionDAO.

About the patch... You're right, Tiles core has become too complicated, I hope 
to simplify it in Tiles 3.

> Simultaneous definition requests to multiple locales causes 
> NoSuchDefinitionException on anonymousDefinition
> ------------------------------------------------------------------------------------------------------------
>
>                 Key: TILES-513
>                 URL: https://issues.apache.org/jira/browse/TILES-513
>             Project: Tiles
>          Issue Type: Bug
>          Components: tiles-core
>    Affects Versions: 2.1.4, 2.2.2
>            Reporter: Jamie Goodfellow
>            Assignee: Antonio Petrelli
>   Original Estimate: 0h
>  Remaining Estimate: 0h
>
> When simultaneously loading the same tiles definition for two locales (in my 
> case, en_CA and es_CO) and a third empty locale, they empty locale request 
> results in a stack trace claiming an anonymous definition could not be found. 
>  I traced this to a synchronization issue in CachingLocaleUrlDefinitionDAO 
> and ResolvingLocaleUrlDefinitionDAO.  The issue seems to be that the 
> loadParentDefinitions method loads the parent locale definitions into the 
> locale2definitionMap map regardless if the map already contains an entry for 
> the requested locale.  Alone this is fine, since the update is synchronized 
> in a previous method call in the stack trace.  However when the three 
> requests come in simultaneously, and the requested definition has nested 
> anonymous definitions, there is a timing issue.
> The first request (say en_CA) requests the root definition (in this case 
> 'security/login').  This causes the root, en, and en_CA definition maps to be 
> loaded.  At the same time, the second request (es_CO) requests the 
> 'security/login' definition.  This will cause the root, es, and es_CO 
> definitions to be loaded (overwriting the root locale with new anonymous 
> definitions).  The third request (empty locale) will request the 
> 'security/login' definition as well.  The definition processing will then see 
> that the security/login definition references other definitions, and begin 
> requesting anonymous definitions.  However, since the root locale has been 
> overwritten, the requested definitions no longer appear in the root map.  
> This results in the stack trace below.
> Appended below are my tiles definition configurations and the stack trace, 
> for reference.  I've also applied a fix for myself.  In Tiles 2.2.2, I 
> updated the loadParentDefinitions in ResolvingLocaleUrlDefinitionDAO to check 
> if the map already contains an entry for the requested locale, and returns 
> the existing entry if so:
>     @Override
>     protected Map<String, Definition> loadParentDefinitions(Locale 
> parentLocale) {
>       if(locale2definitionMap.containsKey(parentLocale)) {
>               return 
> copyDefinitionMap(locale2definitionMap.get(parentLocale));
>       } else {
>               return loadDefinitionsFromURLs(parentLocale);
>       }
>     }
> I've verified this fixes my issue.
>       <!-- Authentication Layout -->
>       <definition name="authLayout" template="/WEB-INF/layouts/auth.jsp">
>               <put-attribute name="header">
>                       <definition template="/WEB-INF/layouts/auth/header.jsp" 
> />
>               </put-attribute>
>               <put-attribute name="localnav">
>                       <definition 
> template="/WEB-INF/layouts/auth/localnav.jsp" />
>               </put-attribute>
>               <put-attribute name="footer">
>                       <definition template="/WEB-INF/layouts/auth/footer.jsp" 
> />
>               </put-attribute>
>       </definition>
>       <!-- index page -->
>       <definition name="security/login" extends="authLayout">
>               <put-attribute name="title" value="page.title.security.login" />
>               <put-attribute name="navTab" value="security" />
>               <put-attribute name="main" 
> value="/WEB-INF/views/security/login.jsp" />
>       </definition>
> org.apache.tiles.definition.NoSuchDefinitionException: $anonymousDefinition7
>       
> org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:625)
>       
> org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:321)
>       
> org.apache.tiles.renderer.impl.DefinitionAttributeRenderer.write(DefinitionAttributeRenderer.java:56)
>       
> org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
>       
> org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:670)
>       
> org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:336)
>       
> org.apache.tiles.template.InsertAttributeModel.renderAttribute(InsertAttributeModel.java:210)
>       
> org.apache.tiles.template.InsertAttributeModel.end(InsertAttributeModel.java:126)
>       
> org.apache.tiles.jsp.taglib.InsertAttributeTag.doTag(InsertAttributeTag.java:311)
>       
> org.apache.jsp.WEB_002dINF.layouts.auth_jsp._jspx_meth_tiles_005finsertAttribute_005f0(auth_jsp.java:899)
>       
> org.apache.jsp.WEB_002dINF.layouts.auth_jsp._jspService(auth_jsp.java:228)
>       org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
>       javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
>       
> org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
>       org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
>       org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
>       javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
>       
> org.apache.tiles.servlet.context.ServletTilesRequestContext.forward(ServletTilesRequestContext.java:241)
>       
> org.apache.tiles.servlet.context.ServletTilesRequestContext.dispatch(ServletTilesRequestContext.java:222)
>       
> org.apache.tiles.renderer.impl.TemplateAttributeRenderer.write(TemplateAttributeRenderer.java:44)
>       
> org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
>       
> org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:670)
>       
> org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:690)
>       
> org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:644)
>       
> org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:627)
>       
> org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:321)
>       
> org.springframework.web.servlet.view.tiles2.TilesView.renderMergedOutputModel(TilesView.java:124)
>       
> org.springframework.js.ajax.tiles2.AjaxTilesView.renderMergedOutputModel(AjaxTilesView.java:115)
>       
> org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
>       
> org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1063)
>       
> org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:801)
>       
> org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
>       
> org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
>       
> org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
>       javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
>       javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
>       
> com.truecontext.prontoforms.pes.aspect.audit.impl.filter.AuditContextSettingFilter.doFilterInternal(AuditContextSettingFilter.java:50)
>       
> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
>       
> org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
>       
> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
>       
> org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:113)
>       
> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
>       
> com.truecontext.prontoforms.pes.web.filter.IncompleteUserFilter.doFilterInternal(IncompleteUserFilter.java:50)
>       
> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
>       
> org.springframework.web.filter.AbstractRequestLoggingFilter.doFilterInternal(AbstractRequestLoggingFilter.java:193)
>       
> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
>       
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:343)
>       
> org.springframework.security.web.authentication.switchuser.SwitchUserFilter.doFilter(SwitchUserFilter.java:177)
>       
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
>       
> org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
>       
> org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
>       
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
>       
> org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
>       
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
>       
> org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
>       
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
>       
> org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
>       
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
>       
> org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:112)
>       
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
>       
> org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
>       
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
>       
> org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
>       
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
>       
> com.truecontext.common.web.aspects.security.authentication.www.UrlSpecificBasicAuthenticationFilter.doFilter(UrlSpecificBasicAuthenticationFilter.java:105)
>       
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
>       
> org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:188)
>       
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
>       
> org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
>       
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
>       
> org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
>       
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
>       
> org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149)
>       
> org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
>       
> org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
>       
> org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
>       
> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
>       
> org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInternal(ShallowEtagHeaderFilter.java:57)
>       
> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to