Author: markt Date: Thu Mar 10 14:22:51 2016 New Revision: 1734418 URL: http://svn.apache.org/viewvc?rev=1734418&view=rev Log: Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=57583 Improve long standing performance issue with EL and undefined attributes.
Modified: tomcat/trunk/java/javax/servlet/jsp/el/ScopedAttributeELResolver.java tomcat/trunk/java/org/apache/el/parser/AstIdentifier.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/javax/servlet/jsp/el/ScopedAttributeELResolver.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/javax/servlet/jsp/el/ScopedAttributeELResolver.java?rev=1734418&r1=1734417&r2=1734418&view=diff ============================================================================== --- tomcat/trunk/java/javax/servlet/jsp/el/ScopedAttributeELResolver.java (original) +++ tomcat/trunk/java/javax/servlet/jsp/el/ScopedAttributeELResolver.java Thu Mar 10 14:22:51 2016 @@ -35,6 +35,20 @@ import javax.servlet.jsp.PageContext; */ public class ScopedAttributeELResolver extends ELResolver { + // Indicates if a performance short-cut is available + private static final Class<?> AST_IDENTIFIER_KEY; + + static { + Class<?> key = null; + try { + key = Class.forName("org.apache.el.parser.AstIdentifier"); + } catch (Exception e) { + // Ignore: Expected if not running on Tomcat. Not a problem since + // this just allows a short-cut. + } + AST_IDENTIFIER_KEY = key; + } + @Override public Object getValue(ELContext context, Object base, Object property) { if (context == null) { @@ -51,10 +65,26 @@ public class ScopedAttributeELResolver e result = page.findAttribute(key); if (result == null) { + boolean resolveClass = true; + // Performance short-cut available when running on Tomcat + if (AST_IDENTIFIER_KEY != null) { + // Tomcat will set this key to Boolean.TRUE if the + // identifier is a stand-alone identifier (i.e. + // identifier) rather than part of an AstValue (i.e. + // identifier.something). Imports do not need to be + // checked if this is a stand-alone identifier + Boolean value = (Boolean) context.getContext(AST_IDENTIFIER_KEY); + if (value != null && value.booleanValue()) { + resolveClass = false; + } + } // This might be the name of an imported class ImportHandler importHandler = context.getImportHandler(); if (importHandler != null) { - Class<?> clazz = importHandler.resolveClass(key); + Class<?> clazz = null; + if (resolveClass) { + clazz = importHandler.resolveClass(key); + } if (clazz != null) { result = new ELClass(clazz); } Modified: tomcat/trunk/java/org/apache/el/parser/AstIdentifier.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/AstIdentifier.java?rev=1734418&r1=1734417&r2=1734418&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/el/parser/AstIdentifier.java (original) +++ tomcat/trunk/java/org/apache/el/parser/AstIdentifier.java Thu Mar 10 14:22:51 2016 @@ -77,7 +77,27 @@ public final class AstIdentifier extends // EL Resolvers ctx.setPropertyResolved(false); - Object result = ctx.getELResolver().getValue(ctx, null, this.image); + Object result; + /* Putting the Boolean into the ELContext is part of a performance + * optimisation for ScopedAttributeELResolver. When looking up "foo", + * the resolver can't differentiate between ${ foo } and ${ foo.bar }. + * This is important because the expensive class lookup only needs to + * be performed in the later case. This flag tells the resolver if the + * lookup can be skipped. + */ + if (parent instanceof AstValue) { + ctx.putContext(this.getClass(), Boolean.FALSE); + } else { + ctx.putContext(this.getClass(), Boolean.TRUE); + } + try { + result = ctx.getELResolver().getValue(ctx, null, this.image); + } finally { + // Always reset the flag to false so the optimisation is not applied + // inappropriately + ctx.putContext(this.getClass(), Boolean.FALSE); + } + if (ctx.isPropertyResolved()) { return result; } Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1734418&r1=1734417&r2=1734418&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Thu Mar 10 14:22:51 2016 @@ -222,6 +222,12 @@ <update> Update to the Eclipse JDT Compiler 4.5.1. (markt) </update> + <fix> + <bug>57583</bug>: Improve the performance of + <code>javax.servlet.jsp.el.ScopedAttributeELResolver</code> when + resolving attributes that do not exist. This improvement only works when + Jasper is used with with Tomcat's EL implementation. (markt) + </fix> </changelog> </subsection> <subsection name="WebSocket"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org