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 >> > > -- Thanks, Daniel Dekany
