This is an automated email from the ASF dual-hosted git repository.
remm pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push:
new cfe38ddecf Make dependent ordering predictable
cfe38ddecf is described below
commit cfe38ddecf1c85e167e472aa6c76b8c708cc0b74
Author: remm <[email protected]>
AuthorDate: Tue Apr 7 11:10:59 2026 +0200
Make dependent ordering predictable
Patch submitted by Jan Luehe.
---
java/org/apache/jasper/compiler/Generator.java | 2 +-
java/org/apache/jasper/compiler/PageInfo.java | 3 +-
test/org/apache/jasper/compiler/TestGenerator.java | 43 ++++++++++++++++++++++
test/webapp/jsp/generator/dependants-order-a.jspf | 17 +++++++++
test/webapp/jsp/generator/dependants-order-b.jspf | 17 +++++++++
test/webapp/jsp/generator/dependants-order-c.jspf | 17 +++++++++
test/webapp/jsp/generator/dependants-order.jsp | 19 ++++++++++
webapps/docs/changelog.xml | 8 ++++
8 files changed, 124 insertions(+), 2 deletions(-)
diff --git a/java/org/apache/jasper/compiler/Generator.java
b/java/org/apache/jasper/compiler/Generator.java
index eec7eecca7..1bbe54e8e6 100644
--- a/java/org/apache/jasper/compiler/Generator.java
+++ b/java/org/apache/jasper/compiler/Generator.java
@@ -567,7 +567,7 @@ class Generator {
if (!dependants.isEmpty()) {
out.printil("static {");
out.pushIndent();
- out.printin("_jspx_dependants = new
java.util.HashMap<java.lang.String,java.lang.Long>(");
+ out.printin("_jspx_dependants = new
java.util.LinkedHashMap<java.lang.String,java.lang.Long>(");
out.print("" + dependants.size());
out.println(");");
for (Entry<String,Long> entry : dependants.entrySet()) {
diff --git a/java/org/apache/jasper/compiler/PageInfo.java
b/java/org/apache/jasper/compiler/PageInfo.java
index 8bb483a8e1..91ba94b5db 100644
--- a/java/org/apache/jasper/compiler/PageInfo.java
+++ b/java/org/apache/jasper/compiler/PageInfo.java
@@ -21,6 +21,7 @@ import java.util.Collection;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -107,7 +108,7 @@ public class PageInfo {
this.jspPrefixMapper = new HashMap<>();
this.xmlPrefixMapper = new HashMap<>();
this.nonCustomTagPrefixMap = new HashMap<>();
- this.dependants = new HashMap<>();
+ this.dependants = new LinkedHashMap<>();
this.includePrelude = new ArrayList<>();
this.includeCoda = new ArrayList<>();
this.pluginDcls = new ArrayList<>();
diff --git a/test/org/apache/jasper/compiler/TestGenerator.java
b/test/org/apache/jasper/compiler/TestGenerator.java
index 01d70ae8b6..e53320c455 100644
--- a/test/org/apache/jasper/compiler/TestGenerator.java
+++ b/test/org/apache/jasper/compiler/TestGenerator.java
@@ -22,8 +22,12 @@ import java.beans.PropertyDescriptor;
import java.beans.PropertyEditorSupport;
import java.io.File;
import java.io.IOException;
+import java.lang.reflect.Field;
import java.nio.charset.CodingErrorAction;
+import java.util.ArrayList;
import java.util.Date;
+import java.util.List;
+import java.util.Map;
import java.util.Scanner;
import javax.servlet.http.HttpServletResponse;
@@ -48,6 +52,7 @@ import org.apache.catalina.Wrapper;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
import org.apache.jasper.servlet.JasperInitializer;
+import org.apache.jasper.servlet.JspServlet;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.compat.JreCompat;
@@ -776,6 +781,44 @@ public class TestGenerator extends TomcatBaseTest {
doTestJsp("include-01.jsp");
}
+ /*
+ * Verify that _jspx_dependants entries appear in the same order as the
+ * <%@ include file="..." %> directives in the source JSP, ensuring
+ * reproducible builds (LinkedHashMap preserves insertion order).
+ */
+ @Test
+ public void testDependantsOrder() throws Exception {
+ Tomcat tomcat = getTomcatInstanceTestWebapp(false, true);
+
+ ByteChunk body = new ByteChunk();
+ int rc = getUrl("http://localhost:" + getPort() +
+ "/test/jsp/generator/dependants-order.jsp", body, null);
+ Assert.assertEquals(body.toString(), HttpServletResponse.SC_OK, rc);
+
+ // JSP classes are loaded by a per-JSP JasperLoader child classloader,
+ // not by the webapp classloader. Retrieve the dependants map through
+ // the JspServletWrapper, which calls getDependants() on the live
+ // servlet instance via the JspSourceDependent interface.
+ Context ctx = (Context) tomcat.getHost().findChild("/test");
+ Wrapper jspWrapper = (Wrapper) ctx.findChild("jsp");
+ JspServlet jspServlet = (JspServlet) jspWrapper.getServlet();
+ Field rctxtField = JspServlet.class.getDeclaredField("rctxt");
+ rctxtField.setAccessible(true);
+ JspRuntimeContext rctxt = (JspRuntimeContext)
rctxtField.get(jspServlet);
+ Map<String,Long> dependants = rctxt.getWrapper(
+ "/jsp/generator/dependants-order.jsp").getDependants();
+
+ // Expect exactly the three fragments, in directive order: a, b, c.
+ List<String> keys = new ArrayList<>(dependants.keySet());
+ Assert.assertEquals(3, keys.size());
+ Assert.assertTrue("a.jspf should precede b.jspf in _jspx_dependants",
+ keys.indexOf("/jsp/generator/dependants-order-a.jspf") <
+ keys.indexOf("/jsp/generator/dependants-order-b.jspf"));
+ Assert.assertTrue("b.jspf should precede c.jspf in _jspx_dependants",
+ keys.indexOf("/jsp/generator/dependants-order-b.jspf") <
+ keys.indexOf("/jsp/generator/dependants-order-c.jspf"));
+ }
+
@Test
public void testSetProperty01() throws Exception {
doTestJsp("setproperty-01.jsp");
diff --git a/test/webapp/jsp/generator/dependants-order-a.jspf
b/test/webapp/jsp/generator/dependants-order-a.jspf
new file mode 100644
index 0000000000..34633181f6
--- /dev/null
+++ b/test/webapp/jsp/generator/dependants-order-a.jspf
@@ -0,0 +1,17 @@
+<%--
+ 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.
+ --%>
+a
\ No newline at end of file
diff --git a/test/webapp/jsp/generator/dependants-order-b.jspf
b/test/webapp/jsp/generator/dependants-order-b.jspf
new file mode 100644
index 0000000000..740112ad77
--- /dev/null
+++ b/test/webapp/jsp/generator/dependants-order-b.jspf
@@ -0,0 +1,17 @@
+<%--
+ 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.
+ --%>
+b
\ No newline at end of file
diff --git a/test/webapp/jsp/generator/dependants-order-c.jspf
b/test/webapp/jsp/generator/dependants-order-c.jspf
new file mode 100644
index 0000000000..983395058d
--- /dev/null
+++ b/test/webapp/jsp/generator/dependants-order-c.jspf
@@ -0,0 +1,17 @@
+<%--
+ 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.
+ --%>
+c
\ No newline at end of file
diff --git a/test/webapp/jsp/generator/dependants-order.jsp
b/test/webapp/jsp/generator/dependants-order.jsp
new file mode 100644
index 0000000000..aa3b60a95a
--- /dev/null
+++ b/test/webapp/jsp/generator/dependants-order.jsp
@@ -0,0 +1,19 @@
+<%--
+ 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.
+ --%>
+<%@ include file="dependants-order-a.jspf" %>
+<%@ include file="dependants-order-b.jspf" %>
+<%@ include file="dependants-order-c.jspf" %>
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 260f37f8d9..1f5e40dc4c 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -182,6 +182,14 @@
</fix>
</changelog>
</subsection>
+ <subsection name="Jasper">
+ <changelog>
+ <fix>
+ <bug>69995</bug>: Make dependent ordering predictable. Patch submitted
+ by Jan Luehe. (remm)
+ </fix>
+ </changelog>
+ </subsection>
<subsection name="Cluster">
<changelog>
<fix>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]