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 >
