You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tiles.apache.org by Eric B <eb...@hotmail.com> on 2013/10/26 07:20:28 UTC
OptionsRenderer not working
I have spent a lot of time on this today, trying to debug & understand
how the OptionsRenderer is working, but failing at it. I don't know the
internals of Tiles too much, so I'm a bit at a loss of understanding all
the contexts that are being pushed onto a stack and looked up/popped off.
Essentially, the error I get when trying to use the OptionsRenderer is:
java.lang.IllegalStateException: A matching list-attribute
name="my_opts" must be defined.
I tried to follow as best as possible the instructions on the
http://tech.finn.no/2012/07/25/the-ultimate-view-tiles-3/4/ site, but
the instructions seem rather old and obsolete and some classes
referenced no longer exist in Spring 3.2.4 and/or are configured
differently.
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.
I also note that this is an ongoing problem for several people already,
but no solution(s) have been proposed. Ex:
http://dhruvgairola.blogspot.de/2013/03/spring-mvc-with-apache-tiles-3.html,
https://issues.apache.org/jira/browse/TILES-569, etc.
I have tried to instantiate the OptionsRenderer as follows:
public class TilesContainerFactory extends
CompleteAutoloadTilesContainerFactory {
@Override
protected Renderer createTemplateAttributeRenderer(BasicRendererFactory
rendererFactory, ApplicationContext applicationContext, TilesContainer
container,
AttributeEvaluatorFactory attributeEvaluatorFactory) {
Renderer renderer =
super.createTemplateAttributeRenderer(rendererFactory,
applicationContext, container, attributeEvaluatorFactory);
// create an Options Renderer
OptionsRenderer optionsRenderer = new
OptionsRenderer(applicationContext, renderer);
return optionsRenderer;
}
}
Can someone please explain if/how to get this class to work?
Thanks,
Eric
Re: OptionsRenderer not working
Posted by Eric B <eb...@hotmail.com>.
On 13-10-27 8:49 PM, Eric B wrote:
> On 13-10-27 3:18 PM, Mick Semb Wever wrote:> ClamAV 0.96.5
> >
> >
> >> Some extra questions while i keep looking…
> >> - are you using tiles-request-1.0.3, tiles-autotag-1.1, and tiles-3.0.1
> >> - have you the spring xml configured like in http://bit.ly/1imSa9T
> >> - and if so can you share your tilesInitializer and container classes
> >
> > Could you also post a stack trace when the code is in
> > OptionsRenderer.render(..)
> >
> > ~mck
> >
> >
>
>
>
> Was using tiles-3.0.1 and it didn't work so I reverted to Tiles 3.0.0 and had the same problems.
>
> Stack trace when in OptionsRenderer.render() (I've attached an screenshot of the context variable as retrieved by line 144 of
> BasicTilesContainer.getAttributeContext()):
>
> Daemon Thread [http-bio-8880-exec-1] (Suspended)
> owns: SocketWrapper (id=11250)
> BasicTilesContainer.getAttributeContext(Request) line: 144
> OptionsRenderer.render(String, Request) line: 96
> ChainedDelegateRenderer.render(String, Request) line: 68
> BasicTilesContainer.render(Attribute, Request) line: 259
> InsertAttributeModel.renderAttribute(TilesContainer, boolean, Attribute, Request) line: 188
> InsertAttributeModel.execute(boolean, String, String, Object, String, String, String, Attribute, boolean, Request, ModelBody) line: 132
> InsertAttributeTag.doTag() line: 300
> default.jsp line: 13
> default.jsp line: not available
> default_jsp(HttpJspBase).service(HttpServletRequest, HttpServletResponse) line: 70
> default_jsp(HttpServlet).service(ServletRequest, ServletResponse) line: 728
> default.jsp line: not available
> JspServletWrapper.service(HttpServletRequest, HttpServletResponse, boolean) line: 432
> JspServlet._serviceJspFile(HttpServletRequest, HttpServletResponse, String, boolean) line: 390
> JspServlet.serviceJspFile(HttpServletRequest, HttpServletResponse, String, boolean) line: not available
> JspServlet.service(HttpServletRequest, HttpServletResponse) line: 334
> JspServlet(HttpServlet).service(ServletRequest, ServletResponse) line: 728
> ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 305
> ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 210
> ApplicationDispatcher.invoke(ServletRequest, ServletResponse, ApplicationDispatcher$State) line: 749
> ApplicationDispatcher.processRequest(ServletRequest, ServletResponse, ApplicationDispatcher$State) line: 487
> ApplicationDispatcher.doForward(ServletRequest, ServletResponse) line: 412
> ApplicationDispatcher.forward(ServletRequest, ServletResponse) line: 339
> TilesView$2(ServletRequest).forward(String) line: 265
> TilesView$2(ServletRequest).doForward(String) line: 228
> TilesView$2(AbstractClientRequest).dispatch(String) line: 57
> DispatchRenderer.render(String, Request) line: 45
> OptionsRenderer.render(String, Request) line: 116
> BasicTilesContainer.render(Attribute, Request) line: 259
> BasicTilesContainer.render(Request, AttributeContext) line: 397
> BasicTilesContainer.render(Definition, Request) line: 238
> 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
> ...
> ...
>
>
>
>
> Spring Config:
> <!-- Tiles page resolver -->
> <bean class="org.springframework.web.servlet.view.tiles3.SpringWildcardServletTilesApplicationContext" autowire="constructor" />
> <bean id="viewResolver" class="org.springframework.web.servlet.view.tiles3.TilesViewResolver" >
> <property name="cache" value="false"/>
> <property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView" />
> </bean>
>
> <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
> <property name="tilesInitializer">
> <bean class="com.ia.system.tiles3.TilesInitializer" />
> </property>
> </bean>
>
>
>
>
> TilesInitializer.java:
> public class TilesInitializer extends AbstractTilesInitializer {
>
> @Override
> protected AbstractTilesContainerFactory createContainerFactory(ApplicationContext context) {
> return new TilesContainerFactory();
> }
>
> }
>
>
> TilesContainerFactory.java:
> public class TilesContainerFactory extends BasicTilesContainerFactory {
> @Override
> protected Renderer createTemplateAttributeRenderer(BasicRendererFactory rendererFactory, ApplicationContext applicationContext, TilesContainer
> container,
> AttributeEvaluatorFactory attributeEvaluatorFactory) {
> Renderer renderer = super.createTemplateAttributeRenderer(rendererFactory, applicationContext, container, attributeEvaluatorFactory);
> OptionsRenderer optionsRenderer = new OptionsRenderer(applicationContext, renderer);
> return optionsRenderer;
> }
>
> @Override
> protected <T> PatternDefinitionResolver<T> createPatternDefinitionResolver(Class<T> customizationKeyClass) {
> PrefixedPatternDefinitionResolver<T> r = new PrefixedPatternDefinitionResolver<T>();
> r.registerDefinitionPatternMatcherFactory("WILDCARD", new WildcardDefinitionPatternMatcherFactory());
> r.registerDefinitionPatternMatcherFactory("REGEXP", new RegexpDefinitionPatternMatcherFactory());
> return r;
> }
>
> }
>
Unfortunately, I think my attachment was rejected by the list server. I wanted to show the contextStack as well and show the linked list when in the
OptionsRenderer.render(), but that will likely get rejected as well. In a nutshell, I've got 3 contexts in the LinkedList:
1) BasicAttributeContext (all null)
2) BasicAttributeContext (attributes = tiles.xml)
3) BasicAttributeContext (all null)
I'm not sure who pushes the 3 contexts on the stack, or more importantly when (have had some trouble understanding the exact flow of when/how the
contexts are pushed on), but I figure there is an issue with the fact that Contexts #1 & 3 are all null.
Re: OptionsRenderer not working
Posted by Eric B <eb...@hotmail.com>.
On 13-10-27 3:18 PM, Mick Semb Wever wrote:> ClamAV 0.96.5
>
>
>> Some extra questions while i keep looking…
>> - are you using tiles-request-1.0.3, tiles-autotag-1.1, and tiles-3.0.1
>> - have you the spring xml configured like in http://bit.ly/1imSa9T
>> - and if so can you share your tilesInitializer and container classes
>
> Could you also post a stack trace when the code is in
> OptionsRenderer.render(..)
>
> ~mck
>
>
Was using tiles-3.0.1 and it didn't work so I reverted to Tiles 3.0.0 and had the same problems.
Stack trace when in OptionsRenderer.render() (I've attached an screenshot of the context variable as retrieved by line 144 of
BasicTilesContainer.getAttributeContext()):
Daemon Thread [http-bio-8880-exec-1] (Suspended)
owns: SocketWrapper (id=11250)
BasicTilesContainer.getAttributeContext(Request) line: 144
OptionsRenderer.render(String, Request) line: 96
ChainedDelegateRenderer.render(String, Request) line: 68
BasicTilesContainer.render(Attribute, Request) line: 259
InsertAttributeModel.renderAttribute(TilesContainer, boolean, Attribute, Request) line: 188
InsertAttributeModel.execute(boolean, String, String, Object, String, String, String, Attribute, boolean, Request, ModelBody) line: 132
InsertAttributeTag.doTag() line: 300
default.jsp line: 13
default.jsp line: not available
default_jsp(HttpJspBase).service(HttpServletRequest, HttpServletResponse) line: 70
default_jsp(HttpServlet).service(ServletRequest, ServletResponse) line: 728
default.jsp line: not available
JspServletWrapper.service(HttpServletRequest, HttpServletResponse, boolean) line: 432
JspServlet._serviceJspFile(HttpServletRequest, HttpServletResponse, String, boolean) line: 390
JspServlet.serviceJspFile(HttpServletRequest, HttpServletResponse, String, boolean) line: not available
JspServlet.service(HttpServletRequest, HttpServletResponse) line: 334
JspServlet(HttpServlet).service(ServletRequest, ServletResponse) line: 728
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 305
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 210
ApplicationDispatcher.invoke(ServletRequest, ServletResponse, ApplicationDispatcher$State) line: 749
ApplicationDispatcher.processRequest(ServletRequest, ServletResponse, ApplicationDispatcher$State) line: 487
ApplicationDispatcher.doForward(ServletRequest, ServletResponse) line: 412
ApplicationDispatcher.forward(ServletRequest, ServletResponse) line: 339
TilesView$2(ServletRequest).forward(String) line: 265
TilesView$2(ServletRequest).doForward(String) line: 228
TilesView$2(AbstractClientRequest).dispatch(String) line: 57
DispatchRenderer.render(String, Request) line: 45
OptionsRenderer.render(String, Request) line: 116
BasicTilesContainer.render(Attribute, Request) line: 259
BasicTilesContainer.render(Request, AttributeContext) line: 397
BasicTilesContainer.render(Definition, Request) line: 238
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
...
...
Spring Config:
<!-- Tiles page resolver -->
<bean class="org.springframework.web.servlet.view.tiles3.SpringWildcardServletTilesApplicationContext" autowire="constructor" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.tiles3.TilesViewResolver" >
<property name="cache" value="false"/>
<property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView" />
</bean>
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="tilesInitializer">
<bean class="com.ia.system.tiles3.TilesInitializer" />
</property>
</bean>
TilesInitializer.java:
public class TilesInitializer extends AbstractTilesInitializer {
@Override
protected AbstractTilesContainerFactory createContainerFactory(ApplicationContext context) {
return new TilesContainerFactory();
}
}
TilesContainerFactory.java:
public class TilesContainerFactory extends BasicTilesContainerFactory {
@Override
protected Renderer createTemplateAttributeRenderer(BasicRendererFactory rendererFactory, ApplicationContext applicationContext, TilesContainer container,
AttributeEvaluatorFactory attributeEvaluatorFactory) {
Renderer renderer = super.createTemplateAttributeRenderer(rendererFactory, applicationContext, container, attributeEvaluatorFactory);
OptionsRenderer optionsRenderer = new OptionsRenderer(applicationContext, renderer);
return optionsRenderer;
}
@Override
protected <T> PatternDefinitionResolver<T> createPatternDefinitionResolver(Class<T> customizationKeyClass) {
PrefixedPatternDefinitionResolver<T> r = new PrefixedPatternDefinitionResolver<T>();
r.registerDefinitionPatternMatcherFactory("WILDCARD", new WildcardDefinitionPatternMatcherFactory());
r.registerDefinitionPatternMatcherFactory("REGEXP", new RegexpDefinitionPatternMatcherFactory());
return r;
}
}
Re: OptionsRenderer not working
Posted by Mick Semb Wever <mc...@apache.org>.
ClamAV 0.96.5
> Some extra questions while i keep looking…
> - are you using tiles-request-1.0.3, tiles-autotag-1.1, and tiles-3.0.1
> - have you the spring xml configured like in http://bit.ly/1imSa9T
> - and if so can you share your tilesInitializer and container classes
Could you also post a stack trace when the code is in
OptionsRenderer.render(..)
~mck
--
"People only get lost in thought because it is unfamiliar territory."
Paul Fix
| http://github.com/finn-no | http://tech.finn.no |
Re: OptionsRenderer not working
Posted by Mick Semb Wever <mc...@apache.org>.
ClamAV 0.96.5
> Can you give me additional information on how the Contexts are working
> and if my analysis is correct?
Some extra questions while i keep looking…
- are you using tiles-request-1.0.3, tiles-autotag-1.1, and tiles-3.0.1
- have you the spring xml configured like in http://bit.ly/1imSa9T
- and if so can you share your tilesInitializer and container classes
~mck
--
"If you are distressed by anything external, the pain is not due to the
thing itself, but to your estimate of it. This you have the power to
revoke." Marcus Aurelius
| http://github.com/finn-no | http://tech.finn.no |
Re: OptionsRenderer not working
Posted by Mick Semb Wever <mc...@apache.org>.
ClamAV 0.96.5
On Sun, 2013-10-27 at 20:50 +0100, Mick Semb Wever wrote:
> Can you try adding cascading="true" to your defaults list-attribute.
>
> For example like
>
> <put-list-attribute name="defaults" cascading="true">
> <add-attribute value="{1}"/>
> <add-attribute value="common"/>
> </put-list-attribute>
arg…
that would be cascade="true"
and the example like
<put-list-attribute name="defaults" cascade="true">
<add-attribute value="{1}"/>
<add-attribute value="common"/>
</put-list-attribute>
--
"You cant solve your problems with the same level of thinking that
created the problems." Albert Einstein
| http://github.com/finn-no | http://tech.finn.no |
Re: OptionsRenderer not working
Posted by Mick Semb Wever <mc...@apache.org>.
ClamAV 0.96.5
On Mon, 2013-10-28 at 14:20 -0400, Eric B wrote:
> > The article afaik doesn't refer anywhere to specific tiles-3 artifacts,
> > so i'd like to leave it to the reader that they should use the latest
> > available and get tiles-3.0.2 out quickly. (I have to get tiles-master-6
> > out first).
>
> I don't actually see a tiles-3.0.2-SNAPSHOT anywhere. The pom version
> for extras is 3.1-SNAPSHOT. Is there even going to be a 3.0.2
> relelase?
The release of 3.0.2 will happen off the TILES_3_0_X branch.
That fix was first in trunk and then back-ported (w/ r1484309) to the
branch, so the 3.1-SNAPSHOT will work for you.
https://repository.apache.org/content/groups/snapshots/org/apache/tiles/tiles-extras/3.1-SNAPSHOT/
~mck
--
"The rainbow would not be without first the rain." D Donche Jr
| http://github.com/finn-no | http://tech.finn.no |
Re: OptionsRenderer not working
Posted by Eric B <eb...@hotmail.com>.
On 13-10-28 1:59 PM, Mick Semb Wever wrote:
>> In the meantime, I wrote up a hacky Aspect to intercept the
>> RuntimeException and throw the cause instead when OptionRenderer is
>> the caller.
>
> I'll be interested in anything you think makes life easier to debug such
> problems. I know OptionsRenderer can too easily mask the underlying
> problems.
Honestly, not entirely sure. Took me a while to step through everything to get a handle on what was happening. Too many contexts, factories,
initializers, etc for the un-initiated to really follow easily. All my Aspect does at the moment is intercept the SpringWildercardContext
.getResources() method and throws the root cause instead of the RuntimeException if it is being called by OptionsRenderer. But this type of hack is
even worse to actually debug, so would not begin to even suggest something like that.
>
>> Can you please update your Blog with the relevant information in the
>> meantime? ie: ensuring the "cascade=true" is present in the
>> list-attributes and indicate that it requires 3.0.2-SNAPSHOT at the
>> minimum to be functional?
>
> Done for cascade=true.
> The article afaik doesn't refer anywhere to specific tiles-3 artifacts,
> so i'd like to leave it to the reader that they should use the latest
> available and get tiles-3.0.2 out quickly. (I have to get tiles-master-6
> out first).
I don't actually see a tiles-3.0.2-SNAPSHOT anywhere. The pom version for extras is 3.1-SNAPSHOT. Is there even going to be a 3.0.2 relelase?
I think that minimum version numbers in your blog could be very helpful. So that people at least know/understand that to use the built-in classes,
they need at least Spring 3.2 and Tiles 3.0.2. Otherwise, they will be spending hours (ie: me! :)) pulling hair trying to understand why things
aren't working.
Re: OptionsRenderer not working
Posted by Mick Semb Wever <mc...@apache.org>.
ClamAV 0.96.5
> I'm not sure if I am happy or sad to hear that after the numerous
> hours I've spent trying to track this down! :)
Well it was only today we got pass the cascade="true" hindrance and to
the IllegalArgumentException. But still i should have given you the
correct reply straight away and saved you 16hrs!
> In the meantime, I wrote up a hacky Aspect to intercept the
> RuntimeException and throw the cause instead when OptionRenderer is
> the caller.
I'll be interested in anything you think makes life easier to debug such
problems. I know OptionsRenderer can too easily mask the underlying
problems.
> Can you please update your Blog with the relevant information in the
> meantime? ie: ensuring the "cascade=true" is present in the
> list-attributes and indicate that it requires 3.0.2-SNAPSHOT at the
> minimum to be functional?
Done for cascade=true.
The article afaik doesn't refer anywhere to specific tiles-3 artifacts,
so i'd like to leave it to the reader that they should use the latest
available and get tiles-3.0.2 out quickly. (I have to get tiles-master-6
out first).
> Finally, I ran into one last problem with your Blog example, but don't
> want to pollute this thread with cross references. Will create
> another thread with the problem.
I really appreciate your feedback Eric. Keep it coming!
I'll look into setting up a simple working example on github too.
~mck
--
"Do not seek to follow in the footsteps of those of old - seek what they
sought." Matsuo Basho
| http://github.com/finn-no | http://tech.finn.no |
Re: OptionsRenderer not working
Posted by Eric B <eb...@hotmail.com>.
On 13-10-28 1:44 PM, Eric B wrote:
> On 13-10-28 12:08 PM, Mick Semb Wever wrote:
>> ClamAV 0.96.5
>>
>>
>>> But if you read the code, you see that FileNotFound is actually never thrown. Since FileNotFoundException is a subclass of IOException, the exception
>>> is caught and wrapped in an IllegalArgumentException, which is a runtime exception. renderAttempt() only tries to catch FileNotFound exceptions,
>>> which are never actually thrown, and consequently, it is never able to process the different options.
>>
>>
>> Yeah you're quite right! and my very poor memory failed to catch this.
>>
>> OptionsRenderer is already patched to address this
>> http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-extras/src/main/java/org/apache/tiles/extras/renderer/OptionsRenderer.java?r1=1368433&r2=1422025
>>
>>
>> The reason for the ResourceLoader throwing a RuntimeException and not a
>> checked exception is up to Spring, not tiles.
>>
>> I will start the process for a new release of tiles, in the meantime i
>> suggest you continue with tiles-extras-3.0.2-SNAPSHOT.jar
Crap - again I sent my email too soon. I just checked the http://repository.apache.org/snapshots repo, but don't see any tiles-extra-3.0.2-SNAPHSOT
artifact. Is there another tiles snapshot repository? I got the repo link from http://tiles.apache.org/framework/dev/snapshots.html.
Thanks,
Eric
Re: OptionsRenderer not working
Posted by Eric B <eb...@hotmail.com>.
On 13-10-28 12:08 PM, Mick Semb Wever wrote:
> ClamAV 0.96.5
>
>
>> But if you read the code, you see that FileNotFound is actually never thrown. Since FileNotFoundException is a subclass of IOException, the exception
>> is caught and wrapped in an IllegalArgumentException, which is a runtime exception. renderAttempt() only tries to catch FileNotFound exceptions,
>> which are never actually thrown, and consequently, it is never able to process the different options.
>
>
> Yeah you're quite right! and my very poor memory failed to catch this.
>
> OptionsRenderer is already patched to address this
> http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-extras/src/main/java/org/apache/tiles/extras/renderer/OptionsRenderer.java?r1=1368433&r2=1422025
>
> The reason for the ResourceLoader throwing a RuntimeException and not a
> checked exception is up to Spring, not tiles.
>
> I will start the process for a new release of tiles, in the meantime i
> suggest you continue with tiles-extras-3.0.2-SNAPSHOT.jar
>
ACK!
I'm not sure if I am happy or sad to hear that after the numerous hours I've spent trying to track this down! :) Definitely happy to hear that it has
already been resolved though. Would have been even happier had I found references that showed it as a problem already fixed. :) Hopefully if anyone
lands on Tiles-572, it can reflect that it was a bug fixed in 3.0.2.
In the meantime, I wrote up a hacky Aspect to intercept the RuntimeException and throw the cause instead when OptionRenderer is the caller. But your
fix is probably a little easier to follow. My concern with the fix, however, is that you are relying on the toString() of the resource, which is
something someone can modify inadvertently without realizing the downstream problems it would be causing. But it looks fairly safe enough.
Can you please update your Blog with the relevant information in the meantime? ie: ensuring the "cascade=true" is present in the list-attributes and
indicate that it requires 3.0.2-SNAPSHOT at the minimum to be functional?
Finally, I ran into one last problem with your Blog example, but don't want to pollute this thread with cross references. Will create another thread
with the problem.
Thanks,
Eric
Re: OptionsRenderer not working
Posted by Mick Semb Wever <mc...@apache.org>.
ClamAV 0.96.5
> But if you read the code, you see that FileNotFound is actually never thrown. Since FileNotFoundException is a subclass of IOException, the exception
> is caught and wrapped in an IllegalArgumentException, which is a runtime exception. renderAttempt() only tries to catch FileNotFound exceptions,
> which are never actually thrown, and consequently, it is never able to process the different options.
Yeah you're quite right! and my very poor memory failed to catch this.
OptionsRenderer is already patched to address this
http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-extras/src/main/java/org/apache/tiles/extras/renderer/OptionsRenderer.java?r1=1368433&r2=1422025
The reason for the ResourceLoader throwing a RuntimeException and not a
checked exception is up to Spring, not tiles.
I will start the process for a new release of tiles, in the meantime i
suggest you continue with tiles-extras-3.0.2-SNAPSHOT.jar
~mck
--
The arc of the moral universe is long, but it bends toward justice. –
Martin Luther King Jr.
| http://github.com/finn-no | http://tech.finn.no |
Re: OptionsRenderer not working
Posted by Eric B <eb...@hotmail.com>.
On 13-10-28 9:28 AM, Mick Semb Wever wrote:
> ClamAV 0.96.5
>
>
>> I've traced this back to the
>> org.springframework.web.servlet.view.tiles3.SpringWildcardServletTilesApplicationContext.getResources(String)
>
>
> Please remove SpringWildcardServletTilesApplicationContext from your
> spring xml.
>
>
> SpringWildcardServletTilesApplicationContext comes automatically from TilesConfigurer
> ref: https://github.com/spring-projects/spring-framework/commit/42a9285
>
>
>
>> or there is a bug in OptionsRenderer that doesn't properly handle the
>> IllegalArgumentException
>
> It would help to see the stack trace to this IAE.
> But the OptionsRenderer does not fallback when there's an exception in a
> template (jsp) that it has found. In this situation that template is
> broken and the exception is thrown. OptionsRenderer only falls back when
> a template is not found.
I've removed the SpringWildcardServletTilesApplicationContext from the config file, but it does not make a difference. The problem that I've found is
the following code in the SpringWildcardServletTilesAppContext file. Lines 78-99. getResources(String):
public Collection<ApplicationResource> getResources(String path) {
Resource[] resources;
try {
resources = resolver.getResources(path);
} catch (IOException e) {
return Collections.<ApplicationResource> emptyList();
}
Collection<ApplicationResource> resourceList = new ArrayList<ApplicationResource>();
if (resources != null && resources.length > 0) {
for (int i = 0; i < resources.length; i++) {
URL url;
try {
url = resources[i].getURL();
resourceList.add(new URLApplicationResource(url.toExternalForm(), url));
} catch (IOException e) {
// shouldn't happen with the kind of resources we're using
throw new IllegalArgumentException("no URL for " + resources[i].toString(), e);
}
}
}
return resourceList;
}
The OptionsRenderer calls on this method in renderAttempt() at line 124:
if (null != applicationContext.getResource(template)) { // can throw FileNotFoundException !
But if you read the code, you see that FileNotFound is actually never thrown. Since FileNotFoundException is a subclass of IOException, the exception
is caught and wrapped in an IllegalArgumentException, which is a runtime exception. renderAttempt() only tries to catch FileNotFound exceptions,
which are never actually thrown, and consequently, it is never able to process the different options.
A fix should be fairly easy (although a little ugly) in OptionsRenderer.renderAttempt(). It would be to catch the IllegalArgumentException, and see
if the cause is a FileNotFound exception. Alternatively, it would be to modify the SpringWildcardServletTilesApplicationContext.getResources() method
to allow throwing of the raw exception and not just the wrapped RuntimeException.
I tried to look through GitHub histroy on the SpringWildcard file, but see that the getResources() method has always had the same logic in it. But
the history is fairly short. I presume it was merged/created from something else, but don't know what the predecessor was so it is difficult for me
to look and see if this logic changed at somepoint, thereby breaking your OptionsRenderer class.
Thanks,
Eric
Thanks,
Eric
Re: OptionsRenderer not working
Posted by Mick Semb Wever <mc...@apache.org>.
ClamAV 0.96.5
> I've traced this back to the
> org.springframework.web.servlet.view.tiles3.SpringWildcardServletTilesApplicationContext.getResources(String)
Please remove SpringWildcardServletTilesApplicationContext from your
spring xml.
<bean id="viewResolver" class="org.springframework.web.servlet.view.tiles3.TilesViewResolver" >
<property name="cache" value="false"/>
<property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView" />
</bean>
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="tilesInitializer">
<bean class="com.ia.system.tiles3.TilesInitializer" />
</property>
</bean>
SpringWildcardServletTilesApplicationContext comes automatically from TilesConfigurer
ref: https://github.com/spring-projects/spring-framework/commit/42a9285
> or there is a bug in OptionsRenderer that doesn't properly handle the
> IllegalArgumentException
It would help to see the stack trace to this IAE.
But the OptionsRenderer does not fallback when there's an exception in a
template (jsp) that it has found. In this situation that template is
broken and the exception is thrown. OptionsRenderer only falls back when
a template is not found.
~mck
--
"Give me a firm place to stand and I will move the earth." Archimedes
| http://github.com/finn-no | http://tech.finn.no |
Re: OptionsRenderer not working
Posted by Eric B <eb...@hotmail.com>.
On 13-10-27 9:08 PM, Eric B wrote:
> On 13-10-27 3:50 PM, Mick Semb Wever wrote:
>> basicTilesContainer.getAttributeContext(request)
>> should be returning a working AttributeContext for you.
>> It should not be null (or an empty deque) and should not be creating a
>> new one for you.
>>
>> As AttributeContexts are pushed onto the stack, via
>> startContext(request), cascading attributes are copied over.
>>
>> But you haven't configured any of your attributes to be cascading.
>> Can you try adding cascading="true" to your defaults list-attribute.
>>
>> For example like
>>
>> <put-list-attribute name="defaults" cascading="true">
>> <add-attribute value="{1}"/>
>> <add-attribute value="common"/>
>> </put-list-attribute>
>>
>
> I've tried with both cascade="true" and inherit="true", but neither seem to have any effect. What I have noticed is that the only time the "correct"
> context is pushed onto the stack is in BasicTilesContainer.render() (line 235) when it is pushing the subContext onto the stack. Likely due to the
> previous line: subcontext.inherit(definition), where definition seems to be the attributes as listed in the tiles.xml file.
>
> Otherwise, I don't really see anywhere that the "inherit" or "cascade" settings make a difference. Do you know where in the code the cascade/inherit
> settings are examined and where the necessary actions are supposed to take place? B/c the code which retrieves the context from the stack is fairly
> simple - if the context is on the stack, use it, otherwise create a new empty one and push onto the stack
> (BasicTilesContainer.getAttributeContext(request) - line 142).
>
Apparently, I was too hasty in my last message. Tiles.xml changes are usually picked up automatically, but for some reason, they weren't this time.
I restarted the server, and sure enough, with cascade="true", the list-attributes are pushed forward into the new context (still not sure where this
happens in the code). Consequently, they are properly retrieved.
So, am making some progress. However, am hitting more stumbling blocks. When OptionsRenderer is searching for the templates, I get the following
exceptions thrown:
java.lang.IllegalArgumentException: no URL for ServletContext resource [/WEB-INF/views/tiles/secure/login/footer.jsp]
at
org.springframework.web.servlet.view.tiles3.SpringWildcardServletTilesApplicationContext.getResources(SpringWildcardServletTilesApplicationContext.java:94)
at
org.springframework.web.servlet.view.tiles3.SpringWildcardServletTilesApplicationContext.getResource(SpringWildcardServletTilesApplicationContext.java:60)
at org.apache.tiles.extras.renderer.OptionsRenderer.renderAttempt(OptionsRenderer.java:124)
at org.apache.tiles.extras.renderer.OptionsRenderer.render(OptionsRenderer.java:109)
at org.apache.tiles.request.render.ChainedDelegateRenderer.render(ChainedDelegateRenderer.java:68)
at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:259)
at org.apache.tiles.template.InsertAttributeModel.renderAttribute(InsertAttributeModel.java:188)
at org.apache.tiles.template.InsertAttributeModel.execute(InsertAttributeModel.java:132)
at org.apache.tiles.jsp.taglib.InsertAttributeTag.doTag(InsertAttributeTag.java:300)
at org.apache.jsp.WEB_002dINF.views.tiles.layouts.default_jsp._jspx_meth_tiles_005finsertAttribute_005f5(default_jsp.java:319)
at org.apache.jsp.WEB_002dINF.views.tiles.layouts.default_jsp._jspService(default_jsp.java:131)
...
...
at java.lang.Thread.run(Thread.java:724)
Caused by: java.io.FileNotFoundException: ServletContext resource [/WEB-INF/views/tiles/secure/login/footer.jsp] cannot be resolved to URL because it
does not exist
at org.springframework.web.context.support.ServletContextResource.getURL(ServletContextResource.java:154)
at
org.springframework.web.servlet.view.tiles3.SpringWildcardServletTilesApplicationContext.getResources(SpringWildcardServletTilesApplicationContext.java:90)
... 102 more
I've traced this back to the org.springframework.web.servlet.view.tiles3.SpringWildcardServletTilesApplicationContext.getResources(String) method -
line 94 (as indicated in the stacktrace), which ends up wrapping the IO exception in an IllegalArgumentException. OptionsRenderer does not catch the
IllegalArgumentException (only catches FileNotFound and IOExceptions), so it never checks subsequent options in the list, and lets the exception
bubble up the stack and consequently, the options are never actually checked.
So at this point, it would appear that either something changed in SpringWildcardServletTilesApplicationContext that never previously wrapped the
exception, or there is a bug in OptionsRenderer that doesn't properly handle the IllegalArgumentException.
Thanks,
Eric
Re: OptionsRenderer not working
Posted by Eric B <eb...@hotmail.com>.
On 13-10-27 3:50 PM, Mick Semb Wever wrote:
> ClamAV 0.96.5
>
>
>> Can you give me additional information on how the Contexts are working
>> and if my analysis is correct?
>
> And yes you are correct.
>
> basicTilesContainer.getAttributeContext(request)
> should be returning a working AttributeContext for you.
> It should not be null (or an empty deque) and should not be creating a
> new one for you.
>
> As AttributeContexts are pushed onto the stack, via
> startContext(request), cascading attributes are copied over.
>
> But you haven't configured any of your attributes to be cascading.
> Can you try adding cascading="true" to your defaults list-attribute.
>
> For example like
>
> <put-list-attribute name="defaults" cascading="true">
> <add-attribute value="{1}"/>
> <add-attribute value="common"/>
> </put-list-attribute>
>
I've tried with both cascade="true" and inherit="true", but neither seem to have any effect. What I have noticed is that the only time the "correct"
context is pushed onto the stack is in BasicTilesContainer.render() (line 235) when it is pushing the subContext onto the stack. Likely due to the
previous line: subcontext.inherit(definition), where definition seems to be the attributes as listed in the tiles.xml file.
Otherwise, I don't really see anywhere that the "inherit" or "cascade" settings make a difference. Do you know where in the code the cascade/inherit
settings are examined and where the necessary actions are supposed to take place? B/c the code which retrieves the context from the stack is fairly
simple - if the context is on the stack, use it, otherwise create a new empty one and push onto the stack
(BasicTilesContainer.getAttributeContext(request) - line 142).
Thanks,
Eric
Re: OptionsRenderer not working
Posted by Mick Semb Wever <mc...@apache.org>.
ClamAV 0.96.5
> Can you give me additional information on how the Contexts are working
> and if my analysis is correct?
And yes you are correct.
basicTilesContainer.getAttributeContext(request)
should be returning a working AttributeContext for you.
It should not be null (or an empty deque) and should not be creating a
new one for you.
As AttributeContexts are pushed onto the stack, via
startContext(request), cascading attributes are copied over.
But you haven't configured any of your attributes to be cascading.
Can you try adding cascading="true" to your defaults list-attribute.
For example like
<put-list-attribute name="defaults" cascading="true">
<add-attribute value="{1}"/>
<add-attribute value="common"/>
</put-list-attribute>
~mck
--
"misunderstanding is never ended by an argument but by tact, diplomacy,
conciliation and a sympathetic desire to see the other person's
viewpoint" Buddha
| http://github.com/finn-no | http://tech.finn.no |
Re: OptionsRenderer not working
Posted by Eric B <eb...@hotmail.com>.
On 13-10-27 12:55 PM, Eric B wrote:
> 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>
>
P.S. I've tried different names for my attribute list (ie: myopts, my_opts, defaults, etc) in the hope that it was a naming convention problem
(although couldn't see how/why that would an issue) but the error message is always the same (specifying the different list name, of course). In this
particular example, the exception thrown was:
java.lang.IllegalStateException: A matching list-attribute name="defaults" must be defined.
Re: OptionsRenderer not working
Posted by Eric B <eb...@hotmail.com>.
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
Re: OptionsRenderer not working
Posted by Mick Semb Wever <mc...@apache.org>.
ClamAV 0.96.5
> 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.
~mck
--
"There is a theory which states that if ever anyone discovers exactly
what the Universe is for and why it is here, it will instantly disappear
and be replaced by something even more bizarrely inexplicable. There is
another theory which states that this has already happened." Douglas
Adams
| http://github.com/finn-no | http://tech.finn.no |