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

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


The following commit(s) were added to refs/heads/10.1.x by this push:
     new 15120756a9 Follow-up to PR #992.
15120756a9 is described below

commit 15120756a9c06d6276349b49f6f5cffd386a81d3
Author: Mark Thomas <[email protected]>
AuthorDate: Thu Apr 30 15:08:54 2026 +0100

    Follow-up to PR #992.
    
    Reduce code duplication. Extend patch to TagFileProcessor.
    Partially inspired by a CoPilot review.
---
 java/org/apache/jasper/compiler/Compiler.java      | 23 ++++++++-----------
 .../apache/jasper/compiler/TagFileProcessor.java   | 25 ++++++++++++++++-----
 .../apache/jasper/compiler/TagLibraryInfoImpl.java | 19 +---------------
 java/org/apache/tomcat/Jar.java                    | 26 ++++++++++++++++++++++
 webapps/docs/changelog.xml                         |  6 +++++
 5 files changed, 61 insertions(+), 38 deletions(-)

diff --git a/java/org/apache/jasper/compiler/Compiler.java 
b/java/org/apache/jasper/compiler/Compiler.java
index e43c13414c..4ec5ca071a 100644
--- a/java/org/apache/jasper/compiler/Compiler.java
+++ b/java/org/apache/jasper/compiler/Compiler.java
@@ -490,21 +490,16 @@ public abstract class Compiler {
                     if (tldPath == null) {
                         return true;
                     }
-                    if (bangSlash < 0) {
-                        // JAR-level key: check the JAR file's last-modified
-                        URLConnection urlConn = 
tldPath.getUrl().openConnection();
-                        try {
-                            includeLastModified = urlConn.getLastModified();
-                        } finally {
-                            urlConn.getInputStream().close();
+                    try (Jar jar = tldPath.openJar()) {
+                        if (jar == null) {
+                            return true;
                         }
-                    } else {
-                        // TLD-entry key: check the entry's last-modified 
within the JAR
-                        String entryName = key.substring(bangSlash + 2);
-                        try (Jar jar = tldPath.openJar()) {
-                            if (jar == null) {
-                                return true;
-                            }
+                        if (bangSlash < 0) {
+                            // JAR-level key: check the JAR file's 
last-modified
+                            includeLastModified = jar.getLastModified();
+                        } else {
+                            // TLD-entry key: check the entry's last-modified 
within the JAR
+                            String entryName = key.substring(bangSlash + 2);
                             includeLastModified = 
jar.getLastModified(entryName);
                         }
                     }
diff --git a/java/org/apache/jasper/compiler/TagFileProcessor.java 
b/java/org/apache/jasper/compiler/TagFileProcessor.java
index 138727e8a3..0514177b46 100644
--- a/java/org/apache/jasper/compiler/TagFileProcessor.java
+++ b/java/org/apache/jasper/compiler/TagFileProcessor.java
@@ -574,18 +574,31 @@ public class TagFileProcessor {
                 String tagFilePath = tagFileInfo.getPath();
                 if (tagFilePath.startsWith("/META-INF/")) {
                     // For tags in JARs, add the TLD and the tag as a 
dependency
-                    TldResourcePath tldResourcePath = 
compiler.getCompilationContext()
-                            
.getTldResourcePath(tagFileInfo.getTagInfo().getTagLibrary().getURI());
-
+                    String tagLibraryUri = 
tagFileInfo.getTagInfo().getTagLibrary().getURI();
+                    TldResourcePath tldResourcePath =
+                            
compiler.getCompilationContext().getTldResourcePath(tagLibraryUri);
+                    String tldWebAppPath = tldResourcePath.getWebappPath();
                     try (Jar jar = tldResourcePath.openJar()) {
 
                         if (jar != null) {
+                            /*
+                             * If the JAR is not in the web application path, 
use the stable Tag Library URI as the
+                             * dependency key to keep the generated code 
deterministic across build environments.
+                             */
+                            String tldKey;
+                            String tagKey;
+                            if (tldWebAppPath == null) {
+                                tldKey = "uri:" + tagLibraryUri + "!/" + 
tldResourcePath.getEntryName();
+                                tagKey = "uri:" + tagLibraryUri + "!/" + 
tagFilePath.substring(1);
+                            } else {
+                                tldKey = 
jar.getURL(tldResourcePath.getEntryName());
+                                tagKey = jar.getURL(tagFilePath.substring(1));
+                            }
                             // Add TLD
-                            
pageInfo.addDependant(jar.getURL(tldResourcePath.getEntryName()),
+                            pageInfo.addDependant(tldKey,
                                     
Long.valueOf(jar.getLastModified(tldResourcePath.getEntryName())));
                             // Add Tag
-                            
pageInfo.addDependant(jar.getURL(tagFilePath.substring(1)),
-                                    
Long.valueOf(jar.getLastModified(tagFilePath.substring(1))));
+                            pageInfo.addDependant(tagKey, 
Long.valueOf(jar.getLastModified(tagFilePath.substring(1))));
                         } else {
                             pageInfo.addDependant(tagFilePath,
                                     
compiler.getCompilationContext().getLastModified(tagFilePath));
diff --git a/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java 
b/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java
index dab1355464..02aae498a4 100644
--- a/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java
+++ b/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java
@@ -23,7 +23,6 @@ import java.io.StringWriter;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
-import java.net.URLConnection;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -137,23 +136,7 @@ class TagLibraryInfoImpl extends TagLibraryInfo implements 
TagConstants {
                         // stable taglib URI as the dependency key instead of 
the
                         // absolute JAR URL to keep the generated servlet code
                         // deterministic across build environments.
-                        URL jarUrl = jar.getJarFileURL();
-                        long lastMod;
-                        URLConnection urlConn = null;
-                        try {
-                            urlConn = jarUrl.openConnection();
-                            lastMod = urlConn.getLastModified();
-                        } catch (IOException ioe) {
-                            throw new JasperException(ioe);
-                        } finally {
-                            if (urlConn != null) {
-                                try {
-                                    urlConn.getInputStream().close();
-                                } catch (IOException ignore) {
-                                    // Ignore
-                                }
-                            }
-                        }
+                        long lastMod = jar.getLastModified();
                         pageInfo.addDependant("uri:" + uriIn, 
Long.valueOf(lastMod));
                     }
                     // Add TLD within the JAR to the dependency list. For 
external
diff --git a/java/org/apache/tomcat/Jar.java b/java/org/apache/tomcat/Jar.java
index 6bb7226790..22aaaedc40 100644
--- a/java/org/apache/tomcat/Jar.java
+++ b/java/org/apache/tomcat/Jar.java
@@ -19,6 +19,7 @@ package org.apache.tomcat;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.net.URLConnection;
 import java.util.jar.Manifest;
 
 /**
@@ -47,6 +48,31 @@ public interface Jar extends AutoCloseable {
      */
     InputStream getInputStream(String name) throws IOException;
 
+    /**
+     * Obtain the last modified time for the JAR.
+     *
+     * @return The time (in the same format as {@link 
System#currentTimeMillis()}) that the resource was last modified.
+     *             Returns -1 if the entry does not exist
+     *
+     * @throws IOException if an I/O error occurs while processing the JAR file
+     */
+    default long getLastModified() throws IOException {
+        URL jarUrl = getJarFileURL();
+        URLConnection urlConn = null;
+        try {
+            urlConn = jarUrl.openConnection();
+            return urlConn.getLastModified();
+        } finally {
+            if (urlConn != null) {
+                try {
+                    urlConn.getInputStream().close();
+                } catch (IOException ignore) {
+                    // Ignore
+                }
+            }
+        }
+    }
+
     /**
      * Obtain the last modified time for the given resource in the JAR.
      *
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 550087d0d7..49ccf66120 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -278,6 +278,12 @@
         <bug>69995</bug>: Make dependent ordering predictable. Patch submitted
         by Jan Luehe. (remm)
       </fix>
+      <fix>
+        <bug>70001</bug>: Ensure JSP compilation is reproducible when
+        dependencies exist for tag files and tag libraries located on the class
+        path but outside of the web application. <pr>992</pr> submitted by Jan
+        Luehe. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Cluster">


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to