[ 
https://issues.apache.org/jira/browse/WW-4062?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13685485#comment-13685485
 ] 

Saulius Tvarijonas commented on WW-4062:
----------------------------------------

Hello Maurizio,

I noticed this problem when was optimizing memory usage in our application. A 
lot of temporary objects was created in velocity template and most of them in 
OgnlParser. I created simple test template to give you more information:
{code}
<h1>Test</h1>
#foreach($a in [1..100])
    <p>$!foo</p>
#end
{code}
Allocation information screenshot is attached. You can see 75% of new allocated 
objects are coming from OgnlUtil#compile. $foo value is null as I described in 
description.
Scope of this problem depends how many times null value is accessed in 
template. I see compile function is costly, but caching solves this problem as 
the same expression is not compiled multiple times. However expressions like 
".literal." are failing and not cached. So in our example it tries to compile 
".literal." expression a hundred times and always fails. So my idea was maybe 
it is possible to cache failed expressions also and not compile again. Or maybe 
there are other ways to reduce calls to #compile.

Please let me know if you need more information to understand this problem.
                
> Invalid OGNL expressions are not cached
> ---------------------------------------
>
>                 Key: WW-4062
>                 URL: https://issues.apache.org/jira/browse/WW-4062
>             Project: Struts 2
>          Issue Type: Bug
>          Components: Value Stack
>    Affects Versions: 2.3.14
>            Reporter: Saulius Tvarijonas
>             Fix For: 2.3.x
>
>         Attachments: WW-4062.PNG
>
>
> I am using velocity to render results page. During performance optimizations 
> I noticed significant memory usage from 
> *com.opensymphony.xwork2.ognl.OgnlUtil#compile*. There is caching implemented 
> in OgnlUtil, but if expression compilation fails, it is not cached.
> I am not really sure if this problem is in struts or velocity engine. But 
> situation is following:
> # In velocity template trying to render string *<p>$!foo</p>*
> # If value is null, velocity calls 
> *org.apache.velocity.runtime.parser.node.ASTReference#getNullString*
> # Internally there is call to *context.get(".literal." + nullString)*
> # And this ".literal." expression always reaches *OgnlUtil#compile* and 
> compilation fails.
> Below is stacktrace for more details:
> {code}
> at com.opensymphony.xwork2.ognl.OgnlUtil.compile(OgnlUtil.java:248)
> at com.opensymphony.xwork2.ognl.OgnlUtil.getValue(OgnlUtil.java:236)
> at 
> com.opensymphony.xwork2.ognl.OgnlValueStack.getValueUsingOgnl(OgnlValueStack.java:291)
> at 
> com.opensymphony.xwork2.ognl.OgnlValueStack.tryFindValue(OgnlValueStack.java:274)
> at 
> com.opensymphony.xwork2.ognl.OgnlValueStack.tryFindValueWhenExpressionIsNotNull(OgnlValueStack.java:256)
> at 
> com.opensymphony.xwork2.ognl.OgnlValueStack.findValue(OgnlValueStack.java:236)
> at 
> com.opensymphony.xwork2.ognl.OgnlValueStack.findValue(OgnlValueStack.java:298)
> at 
> org.apache.struts2.dispatcher.StrutsRequestWrapper.getAttribute(StrutsRequestWrapper.java:82)
> at org.apache.velocity.tools.view.context.ChainedContext.getAttribute(Unknown 
> Source:-1)
> at org.apache.velocity.tools.view.context.ChainedContext.internalGet(Unknown 
> Source:-1)
> at org.apache.velocity.context.AbstractContext.get(AbstractContext.java:193)
> at 
> org.apache.velocity.context.InternalContextAdapterImpl.get(InternalContextAdapterImpl.java:267)
> at 
> org.apache.velocity.runtime.parser.node.ASTReference.getNullString(ASTReference.java:510)
> at 
> org.apache.velocity.runtime.parser.node.ASTReference.render(ASTReference.java:465)
> at 
> org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:342)
> at 
> org.apache.velocity.runtime.parser.node.ASTStringLiteral.value(ASTStringLiteral.java:330)
> at 
> org.apache.velocity.runtime.parser.node.ASTExpression.value(ASTExpression.java:71)
> at 
> org.apache.velocity.runtime.parser.node.ASTSetDirective.render(ASTSetDirective.java:142)
> at 
> org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:342)
> at org.apache.velocity.runtime.directive.Parse.render(Parse.java:260)
> at 
> org.apache.velocity.runtime.parser.node.ASTDirective.render(ASTDirective.java:207)
> at 
> org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:342)
> at org.apache.velocity.Template.merge(Template.java:356)
> at org.apache.velocity.Template.merge(Template.java:260)
> at 
> org.apache.struts2.dispatcher.VelocityResult.doExecute(VelocityResult.java:156)
> at 
> org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186)
> {code}

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to