Just let you know that this patch has been merged into the 2.3.x
branch (which will be 2.3.24). Thanks for the contribution!

Afterwards I did some refactoring in the long existing architecture to
get rid of some unnecessary complexity (which I have noticed during
reviewing this patch), and thus I was able to replace
TemplateElementsToVisit with a simple TemplateElement[], also those
TemplateElement[] are now created during parsing, not for each
executions of the elements.

-- 
Thanks,
 Daniel Dekany


Wednesday, October 14, 2015, 9:18:01 PM, Daniel Dekany wrote:

> Thanks, I will review it more closely as soon as I get to it... like
> there's a slight hope that it will happen this weekend.
>
> Others, please look at this patch and tell your opinions, if you find
> the time! As of me, I have finally decided to let this change in
> (unless I will find some new issue I haven't realized yet).
>
>
> Wednesday, October 14, 2015, 2:35:40 PM, Kleine, Moritz wrote:
>
>> Hi, here¹s the 2.3-gae pull request
>> https://github.com/apache/incubator-freemarker/pull/6
>> Regards,
>> Moritz
>>
>> On 9/11/15, 7:49 PM, "Daniel Dekany" <[email protected]> wrote:
>>
>>>It surely consumes less stack this way, though stack usage doesn't
>>>used to be an concern (barring FTL sequence concatenations in a loop,
>>>but that's another topic). While less stack is just better regardless,
>>>with this change the code becomes a bit more convoluted (especially if
>>>you had to do something after the child elements ran; though if I saw
>>>well, surprisingly, we don't have such case so far). So I would like
>>>to understand why does your application need so deep stack. I would
>>>think that you had to have some ridiculously high number of things
>>>nested into each other to run into this, but maybe I'm wrong.
>>>
>>>
>>>Thursday, September 10, 2015, 3:53:13 PM, Kleine, Moritz wrote:
>>>
>>>> Hi,
>>>>
>>>> we¹re building a website using a view-agnostic document store and a
>>>> spring-based webapp that is capable of rendering views for documents
>>>> that include views of linked documents. The views are typically
>>>> small freemarker templates (at most some tenths of lines) using a
>>>> custom include directive that determines the view for the included
>>>> document and ­ if it is a freemarker template ‹ tells that template to
>>>>process itself.
>>>>
>>>> Now, we¹re frequently running into stackoverflowerrors which
>>>> exhibit the level of inclusion and the whole structure of the
>>>> freemarker templates from the root of up to the custom include. The
>>>> stacktrace fragment shown below ([1]) is taken from such a
>>>> stackoverflowerror. I¹d suggest to adjust the visitor pattern based
>>>> implementation so that the accept calls do not invoke
>>>> Environment#visit again but return the tempate elements to be
>>>> visited. That way we obtain stacktraces that look as shown further
>>>> down below ([2]). The patched code resides here:
>>>> 
>>>>https://github.com/mkleine/incubator-freemarker/tree/avoid-too-much-recur
>>>>sion-when-visiting-template-elements
>>>>
>>>> Are we misusing freemarker or is the approach to reduction of
>>>>stackframes welcome?
>>>>
>>>> Kind regards,
>>>> Moritz
>>>>
>>>>
>>>> [1]
>>>>      at
>>>> freemarker.ext.beans.BeansWrapper.invokeMethod(BeansWrapper.java:1458)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:71)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at freemarker.core.MethodCall._eval(MethodCall.java:62)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at freemarker.core.Expression.eval(Expression.java:78)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.Expression.evalAndCoerceToString(Expression.java:82)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.BuiltInForString._eval(BuiltInForString.java:26)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at freemarker.core.Expression.eval(Expression.java:78)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.Expression.evalAndCoerceToString(Expression.java:82)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.DollarVariable.accept(DollarVariable.java:40)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at freemarker.core.Environment.visit(Environment.java:312)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.MixedContent.accept(MixedContent.java:62)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.Environment.visitByHiddingParent(Environment.java:333)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.ConditionalBlock.accept(ConditionalBlock.java:48)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.Environment.visitByHiddingParent(Environment.java:333)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.Environment.visitAndTransform(Environment.java:413)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.CompressedBlock.accept(CompressedBlock.java:37)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at freemarker.core.Environment.visit(Environment.java:312)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at freemarker.core.Macro$Context.runMacro(Macro.java:178)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at freemarker.core.Environment.invoke(Environment.java:700)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at freemarker.core.UnifiedCall.accept(UnifiedCall.java:84)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.Environment.visitByHiddingParent(Environment.java:333)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.IteratorBlock$Context.runLoop(IteratorBlock.java:148)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.Environment.visitIteratorBlock(Environment.java:559)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.IteratorBlock.accept(IteratorBlock.java:67)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at freemarker.core.Environment.visit(Environment.java:312)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.MixedContent.accept(MixedContent.java:62)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.Environment.visitByHiddingParent(Environment.java:333)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.ConditionalBlock.accept(ConditionalBlock.java:48)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.Environment.visitByHiddingParent(Environment.java:333)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.ConditionalBlock.accept(ConditionalBlock.java:48)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at freemarker.core.Environment.visit(Environment.java:312)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.MixedContent.accept(MixedContent.java:62)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at freemarker.core.Environment.visit(Environment.java:312)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at freemarker.core.EscapeBlock.accept(EscapeBlock.java:48)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at freemarker.core.Environment.visit(Environment.java:312)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at
>>>> freemarker.core.Environment.process(Environment.java:290)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>         at freemarker.template.Template.process(Template.java:312)
>>>>[freemarker-2.3.22.jar:2.3.22]
>>>>
>>>> [2]
>>>>
>>>> at
>>>> freemarker.ext.beans.BeansWrapper.invokeMethod(BeansWrapper.java:1458)
>>>> at
>>>> freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:71)
>>>> at freemarker.core.MethodCall._eval(MethodCall.java:62)
>>>> at freemarker.core.Expression.eval(Expression.java:78)
>>>> at freemarker.core.ReturnInstruction.accept(ReturnInstruction.java:35)
>>>> at freemarker.core.Environment.visit(Environment.java:336)
>>>> at freemarker.core.Macro$Context.runMacro(Macro.java:186)
>>>> at freemarker.core.Environment.invoke(Environment.java:705)
>>>> at freemarker.core.MethodCall._eval(MethodCall.java:74)
>>>> at freemarker.core.Expression.eval(Expression.java:78)
>>>> at
>>>> freemarker.core.Expression.evalAndCoerceToString(Expression.java:82)
>>>> at freemarker.core.DollarVariable.accept(DollarVariable.java:41)
>>>> at freemarker.core.Environment.visit(Environment.java:336)
>>>> at freemarker.core.Environment.visit(Environment.java:341)
>>>> at
>>>> freemarker.core.Environment.renderElementToString(Environment.java:2200)
>>>> at
>>>> 
>>>>freemarker.core.StringLiteral.evalAndCoerceToString(StringLiteral.java:96
>>>>)
>>>> at freemarker.core.StringLiteral._eval(StringLiteral.java:73)
>>>> at freemarker.core.Expression.eval(Expression.java:78)
>>>> at
>>>> 
>>>>freemarker.core.Environment.setMacroContextLocalsFromArguments(Environmen
>>>>t.java:743)
>>>> at freemarker.core.Environment.invoke(Environment.java:693)
>>>> at freemarker.core.UnifiedCall.accept(UnifiedCall.java:85)
>>>> at freemarker.core.Environment.visit(Environment.java:336)
>>>> at freemarker.core.Environment.visit(Environment.java:341)
>>>> at freemarker.core.Environment.visit(Environment.java:341)
>>>> at freemarker.core.Environment.process(Environment.java:302)
>>>> at freemarker.template.Template.process(Template.java:325)
>>>
>>>-- 
>>>Thanks,
>>> Daniel Dekany
>>>
>>
>>
>


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

Reply via email to