On 13-10-27 4:06 AM, Mick Semb Wever wrote:
java.lang.IllegalStateException: A matching list-attribute
name="my_opts" must be defined.
Does the definition this request is using have in your tiles.xml the
"myopts" list attribute defined?
<put-list-attribute name="myopts">
<add-attribute value="{1}"/>
<add-attribute value="common"/>
</put-list-attribute>
From what I can tell, it would appear that the context that the
OptionsRenderer is receiving is not correct; the attributes and
cascadedAttributes are both null, even though they should be set.
However, I have been unable to trace why this is happening.
Odd. Can you post your tiles.xml.
(Or post a reproducible test-case to the issue).
This does sounds like something rather trivial to fix, but i need a
little more information still.
Here is my tiles.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration
3.0//EN" "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
<definition name="REGEXP:([^.]+)"
template="/WEB-INF/views/tiles/layouts/default.jsp">
<put-attribute name="meta"
value="/WEB-INF/views/tiles/${options[defaults]}/meta.jsp"/>
<put-attribute name="head"
value="/WEB-INF/views/tiles/${options[defaults]}/head.jsp"/>
<put-attribute name="header"
value="/WEB-INF/views/tiles/${options[defaults]}/header.jsp"/>
<put-attribute name="menu"
value="/WEB-INF/views/tiles/${options[defaults]}/menu.jsp"/>
<put-attribute name="body"
value="/WEB-INF/views/tiles/${options[defaults]}/body.jsp"/>
<put-attribute name="footer"
value="/WEB-INF/views/tiles/${options[defaults]}/footer.jsp"/>
<put-list-attribute name="defaults">
<add-attribute value="{1}"/>
<add-attribute value="common"/>
</put-list-attribute>
</definition>
</tiles-definitions>
What I've noticed is in the following stacktrace, getContext(request) is null, and consequently, a new BasicAttributeContext() is created and pushed
onto the stack. But the context is empty, and any attempt to retrieve attributes from it are all null.
I presume the concept is that the contexts are stackable; if no attribute is found in the top context, that it should search through the stack for the
first context that has a matching attribute, that does not seem to be happening.
Daemon Thread [http-bio-8880-exec-3] (Suspended (breakpoint at line 143 in
BasicTilesContainer))
owns: SocketWrapper (id=457)
BasicTilesContainer.getAttributeContext(Request) line: 143
BasicTilesContainer.render(Definition, Request) line: 231
BasicTilesContainer.render(String, Request) line: 221
DefinitionRenderer.render(String, Request) line: 59
TilesView.renderMergedOutputModel(Map<String,Object>,
HttpServletRequest, HttpServletResponse) line: 145
TilesView(AbstractView).render(Map<String,?>, HttpServletRequest,
HttpServletResponse) line: 263
DispatcherServlet.render(ModelAndView, HttpServletRequest,
HttpServletResponse) line: 1208
DispatcherServlet.processDispatchResult(HttpServletRequest,
HttpServletResponse, HandlerExecutionChain, ModelAndView, Exception) line: 992
DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse)
line: 939
DispatcherServlet.doService(HttpServletRequest, HttpServletResponse)
line: 856
DispatcherServlet(FrameworkServlet).processRequest(HttpServletRequest,
HttpServletResponse) line: 936
DispatcherServlet(FrameworkServlet).doGet(HttpServletRequest,
HttpServletResponse) line: 827
DispatcherServlet(HttpServlet).service(HttpServletRequest,
HttpServletResponse) line: 621
DispatcherServlet(FrameworkServlet).service(HttpServletRequest,
HttpServletResponse) line: 812
DispatcherServlet(HttpServlet).service(ServletRequest, ServletResponse)
line: 728
ApplicationFilterChain.internalDoFilter(ServletRequest,
ServletResponse) line: 305
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line:
210
FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest,
ServletResponse) line: 330
FilterSecurityInterceptor.invoke(FilterInvocation) line: 118
FilterSecurityInterceptor.doFilter(ServletRequest, ServletResponse,
FilterChain) line: 84
...
...
...
Indeed, if I put a breakpoint in the BasicTilesContext.getContext() method, and search through through contextStack, I see that the top context is
empty and the second in the list has the entire tiles.xml data in the attributes. But I am not entirely clear on how/when these contexts are pushed
onto the stack, and why only the top level context is being examined and not the whole stack.
I'll see if I can put together a small sample app that demonstrates the issue,
but not sure how fast I'll be able to do that.
Can you give me additional information on how the Contexts are working and if
my analysis is correct?
Thanks,
Eric