You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2026/10/19 21:17:17 UTC
(tomcat) 23/46: Use the canonical enum name in optimized tag setter code generation
This is an automated email from the ASF dual-hosted git repository.
rmaucher pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit b70d98f234669acc6fb3518ea9d5552f047b139d
Author: opencode <re...@apache.org>
AuthorDate: Mon Oct 19 11:01:42 2026 +0200
Use the canonical enum name in optimized tag setter code generation
The optional ELInterpreterTagSetters optimization referenced the enum
type of a tag attribute setter by Class.getName(). For a nested enum
that returns the binary name with '$' separators, e.g.
com.example.Tags$Status, which is not valid Java source, so a literal
EL value like ${'ACTIVE'} for a setter taking a nested enum type made
the generated JSP class fail to compile on first request.
Use getCanonicalName() instead, matching the dot-separated name the
non-optimized runtime path in JspUtil.interpreterCall already uses.
Found by code review.
---
.../optimizations/ELInterpreterTagSetters.java | 5 +++-
.../optimizations/TestELInterpreterTagSetters.java | 29 +++++++++++++++++++++
test/webapp/WEB-INF/tag-setters.tld | 11 ++++++++
test/webapp/bug6nnnn/bug64872-nested-timeunit.jsp | 30 ++++++++++++++++++++++
4 files changed, 74 insertions(+), 1 deletion(-)
diff --git a/java/org/apache/jasper/optimizations/ELInterpreterTagSetters.java b/java/org/apache/jasper/optimizations/ELInterpreterTagSetters.java
index 9841e4d5ad..18d88fc659 100644
--- a/java/org/apache/jasper/optimizations/ELInterpreterTagSetters.java
+++ b/java/org/apache/jasper/optimizations/ELInterpreterTagSetters.java
@@ -262,7 +262,10 @@ public class ELInterpreterTagSetters implements ELInterpreter {
try {
@SuppressWarnings({ "unchecked", "rawtypes" })
Enum<?> enumValue = Enum.valueOf((Class<? extends Enum>) expectedType, m.group(2));
- result = expectedType.getName() + "." + enumValue.name();
+ // The canonical name (dot-separated) must be used here. The
+ // binary name returned by getName() contains '$' separators
+ // for nested types and is not valid Java source.
+ result = expectedType.getCanonicalName() + "." + enumValue.name();
} catch (IllegalArgumentException iae) {
if (log.isDebugEnabled()) {
log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2),
diff --git a/test/org/apache/jasper/optimizations/TestELInterpreterTagSetters.java b/test/org/apache/jasper/optimizations/TestELInterpreterTagSetters.java
index 1cdf5bd2c8..e9add535aa 100644
--- a/test/org/apache/jasper/optimizations/TestELInterpreterTagSetters.java
+++ b/test/org/apache/jasper/optimizations/TestELInterpreterTagSetters.java
@@ -90,6 +90,7 @@ public class TestELInterpreterTagSetters extends TomcatBaseTest {
parameterSets.add(new Object[] { elInterpreter, "float", "12.34", ZERO, TWO });
parameterSets.add(new Object[] { elInterpreter, "primitive-float", "12.34", ZERO, TWO });
parameterSets.add(new Object[] { elInterpreter, "timeunit", "SECONDS", ZERO, TWO });
+ parameterSets.add(new Object[] { elInterpreter, "nested-timeunit", "SECONDS", ZERO, TWO });
parameterSets.add(new Object[] { elInterpreter, "string", "bar", ZERO, TWO });
}
return parameterSets;
@@ -473,6 +474,34 @@ public class TestELInterpreterTagSetters extends TomcatBaseTest {
}
+ /*
+ * Enum nested in a class to check the generated code uses the canonical
+ * name of the enum type, not the binary name.
+ */
+ public enum NestedTimeUnit {
+ SECONDS
+ }
+
+
+ public static class TagNestedTimeUnit extends SimpleTagSupport {
+
+ private NestedTimeUnit foo;
+
+ public NestedTimeUnit getFoo() {
+ return foo;
+ }
+
+ public void setFoo(NestedTimeUnit foo) {
+ this.foo = foo;
+ }
+
+ @Override
+ public void doTag() throws JspException, IOException {
+ getJspContext().getOut().print(foo);
+ }
+ }
+
+
public static class TagBigDecimal extends SimpleTagSupport {
private BigDecimal foo;
diff --git a/test/webapp/WEB-INF/tag-setters.tld b/test/webapp/WEB-INF/tag-setters.tld
index e02ae147bd..7158111a54 100644
--- a/test/webapp/WEB-INF/tag-setters.tld
+++ b/test/webapp/WEB-INF/tag-setters.tld
@@ -242,4 +242,15 @@
<type>java.util.concurrent.TimeUnit</type>
</attribute>
</tag>
+ <tag>
+ <name>tagNestedTimeUnit</name>
+ <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagNestedTimeUnit</tag-class>
+ <body-content>scriptless</body-content>
+ <attribute>
+ <name>foo</name>
+ <required>true</required>
+ <rtexprvalue>true</rtexprvalue>
+ <type>org.apache.jasper.optimizations.TestELInterpreterTagSetters$NestedTimeUnit</type>
+ </attribute>
+ </tag>
</taglib>
\ No newline at end of file
diff --git a/test/webapp/bug6nnnn/bug64872-nested-timeunit.jsp b/test/webapp/bug6nnnn/bug64872-nested-timeunit.jsp
new file mode 100644
index 0000000000..621a80945b
--- /dev/null
+++ b/test/webapp/bug6nnnn/bug64872-nested-timeunit.jsp
@@ -0,0 +1,30 @@
+<%--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+--%>
+<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %>
+<html>
+ <head><title>Bug 64872 nested enum test case</title></head>
+ <body>
+ <%
+ for (int i=0; i < Integer.parseInt(request.getParameter("iterations")); i++) {
+ %>
+ <p>01 The value of foo is [<ts:tagNestedTimeUnit foo="${'SECONDS'}" />]</p>
+ <p>02 The value of foo is [<ts:tagNestedTimeUnit foo='${"SECONDS"}' />]</p>
+ <%
+ }
+ %>
+ </body>
+</html>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org