This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
     new 68c92190b0 Use new EL 6.1 marker class for this optimisation
68c92190b0 is described below

commit 68c92190b05b137f47ff3a6f93e47dee04a312b1
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Tue May 13 09:51:06 2025 +0100

    Use new EL 6.1 marker class for this optimisation
---
 java/jakarta/el/ELResolver.java                   | 19 +++++++++++++
 java/jakarta/servlet/jsp/el/ImportELResolver.java | 33 ++++++-----------------
 java/org/apache/el/parser/AstIdentifier.java      |  9 +++----
 webapps/docs/changelog.xml                        |  6 +++++
 4 files changed, 37 insertions(+), 30 deletions(-)

diff --git a/java/jakarta/el/ELResolver.java b/java/jakarta/el/ELResolver.java
index 0b9be0327a..d650069cb0 100644
--- a/java/jakarta/el/ELResolver.java
+++ b/java/jakarta/el/ELResolver.java
@@ -133,4 +133,23 @@ public abstract class ELResolver {
         context.setPropertyResolved(false);
         return null;
     }
+
+    /**
+     * This class is used as a key for {@link ELContext#getContext(Class)}. 
The key references a context object that if
+     * present and set to {@code Boolean#TRUE}, indicates that the identifier 
being resolved is a single, stand-alone
+     * identifier. This allows {@link ELResolver} instances - and in particular
+     * {@code jakarta.servlet.jsp.el.ImportELResolver} - to optimise the 
resolution of the identifier and avoid
+     * unnecessary and expensive class loader lookups.
+     * <p>
+     * The EL implementation is required to set this key with the value {@code 
Boolean#TRUE} when resolving a single,
+     * stand-alone identifier.
+     *
+     * @since Jakarta Expression Language 6.1
+     */
+    public class StandaloneIdentifierMarker {
+
+        private StandaloneIdentifierMarker() {
+            // Non-public default constructor as there is no need to create 
instances of this class.
+        }
+    }
 }
diff --git a/java/jakarta/servlet/jsp/el/ImportELResolver.java 
b/java/jakarta/servlet/jsp/el/ImportELResolver.java
index eb3746bbce..3b003c3a12 100644
--- a/java/jakarta/servlet/jsp/el/ImportELResolver.java
+++ b/java/jakarta/servlet/jsp/el/ImportELResolver.java
@@ -30,20 +30,6 @@ import jakarta.el.ImportHandler;
  */
 public class ImportELResolver 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;
-    }
-
     /**
      * Default constructor.
      */
@@ -60,17 +46,14 @@ public class ImportELResolver extends ELResolver {
         if (base == null) {
             if (property != 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;
-                    }
+                /*
+                 * The EL implementation 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(ELResolver.StandaloneIdentifierMarker.class);
+                if (value != null && value.booleanValue()) {
+                    resolveClass = false;
                 }
 
                 ImportHandler importHandler = context.getImportHandler();
diff --git a/java/org/apache/el/parser/AstIdentifier.java 
b/java/org/apache/el/parser/AstIdentifier.java
index a1f9759932..63b6e89e7a 100644
--- a/java/org/apache/el/parser/AstIdentifier.java
+++ b/java/org/apache/el/parser/AstIdentifier.java
@@ -19,6 +19,7 @@ package org.apache.el.parser;
 
 import jakarta.el.ELClass;
 import jakarta.el.ELException;
+import jakarta.el.ELResolver;
 import jakarta.el.MethodExpression;
 import jakarta.el.MethodInfo;
 import jakarta.el.MethodNotFoundException;
@@ -78,15 +79,13 @@ public final class AstIdentifier extends SimpleNode {
         ctx.setPropertyResolved(false);
         Object result;
         /*
-         * Putting the Boolean into the ELContext is part of a performance 
optimisation for ScopedAttributeELResolver.
+         * Putting the Boolean into the ELContext is part of a performance 
optimisation for ImportELResolver.
          * 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);
+        if (!(parent instanceof AstValue)) {
+            ctx.putContext(ELResolver.StandaloneIdentifierMarker.class, 
Boolean.TRUE);
         }
         try {
             result = ctx.getELResolver().getValue(ctx, null, this.image);
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index c4a2380c74..4cc9bf852b 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -193,6 +193,12 @@
         <code>compilerTargetVM</code> have been updated to 21 to align with 
Java
         21 being the minimum Java version required for Tomcat 12. (markt)
       </update>
+      <scode>
+        Refactor the performance optimisation for
+        <code>jakarta.servlet.jsp.el.ImportELResolver</code> to use the new
+        marker class,
+        <code>jakarta.el.ELResolver.StandaloneIdentifierMarker</code>. (markt)
+      </scode>
       <!-- Entries for backport and removal before 12.0.0-M1 below this line 
-->
     </changelog>
   </subsection>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to