https://bz.apache.org/bugzilla/show_bug.cgi?id=70001

            Bug ID: 70001
           Summary: _jspx_dependants contains non-deterministic absolute
                    JAR paths for taglibs resolved from external JARs
           Product: Tomcat 9
           Version: unspecified
          Hardware: PC
                OS: Mac OS X 10.1
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Jasper
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: -----

When a JSP uses a <%@taglib%> directive whose TLD resides in a JAR that is on
the classpath but not inside the web application's WEB-INF/lib, Jasper records
the TLD dependency in the generated servlet's static _jspx_dependants
initializer using the absolute filesystem URL of the JAR and its TLD entry as
the map key.                                                                    

For example, the directive:                                                     

  <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"; %>               

produces entries such as:                                                       

  _jspx_dependants.put(                                                         
     
"jar:file:/Users/jluehe/.cache/bazel/870f52.../jakarta.servlet.jsp.jstl-2.0.0.jar!/META-INF/c.tld",
 
      Long.valueOf(1602899172000L));                                            

The path encodes the build-environment-specific JAR location (sandbox
directory, local cache path, etc.), so two compilations of an identical JSP in
different environments produce bytecode that differs only in these paths. This
breaks reproducible builds and remote build caching (e.g. with Bazel).          

The root cause is in TagLibraryInfoImpl.java: when
TldResourcePath.getWebappPath() is null (i.e. the JAR is external to the web
application), the code uses jarUrl.toExternalForm() and jar.getURL(entryName)
as the dependency keys — both of which are absolute, environment-specific
paths.


Fix                                                                             

For external JARs (path == null), replace the absolute-path keys with stable,
environment-independent keys derived from the taglib URI declared in the JSP
directive:

  - JAR-level key: "uri:" + uriIn (e.g. uri:http://java.sun.com/jsp/jstl/core)  
  - TLD-entry key: "uri:" + uriIn + "!/" + entryName (e.g.
uri:http://java.sun.com/jsp/jstl/core!/META-INF/c.tld)                          

The taglib URI is a stable, globally unique identifier already present at
compile time. The rest of each block (URLConnection lastMod reads,
jar.getLastModified()) is unchanged.                                            

Compiler.isOutdated() is extended to resolve uri: prefixed keys at runtime
through TldCache.getTldResourcePath(), and based on the presence of “!/”, check
either the JAR file's last-modified (via URLConnection) or the TLD entry's
last-modified (via Jar.getLastModified()).


Verification

$ ant test -Dtest.entry=org.apache.jasper.compiler.TestTagLibraryInfoImpl

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to