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 |