TOMEE-4651 - register the jakarta.tags.* TLD URIs#2844
Open
jungm wants to merge 2 commits into
Open
Conversation
Jakarta Tags 3.0 renamed the JSTL taglib URIs from the legacy http://java.sun.com/jsp/jstl/* form to the short jakarta.tags.* form. The taglibs-standard implementation shaded in deps/taglibs-shade predates that rename. The shade only rewrites bytecode (javax.servlet to jakarta.servlet), it does not touch the TLD descriptors, so the shipped TLDs still declare the legacy URIs only. Any page with <%@ taglib uri="jakarta.tags.core" %> therefore failed at JSP compile time. Register the seven Jakarta Tags URIs as additional keys for the TLD resources TomEETldScanner already pre-populates for their legacy spellings, and widen the permittedTaglibs validator so a page guarded by that TLV may use either spelling. The aliases reuse the very same TldResourcePath instance: scanPlatform() tells myfaces and jstl entries apart by reference identity on the resource path's URL, and TLD_RESOURCE_TAG_LIB is keyed on it. The aliasing is kept out of the dumped data block so hand-written logic stays separate from the pasted TLD metadata, and is a no-op when JSTL is absent. Verified against the Jakarta EE 11 Web Profile TCK, tags partition. With the exclusion lifted the suite goes from all 50 classes failing JSP compilation to 482 of 541 tests passing with no taglib resolution errors left; the 8 classes still failing need Derby tables the harness does not create, or fail resolving an external systemId. The EJB Lite JSP vehicles that broke as a side effect pass again.
rzo1
approved these changes
Jul 21, 2026
- restrict the alias map to the five URIs Jakarta Tags 3.0 actually renamed; permittedTaglibs/scriptfree are Apache-Standard-Taglibs TLVs that kept their legacy URIs, so aliasing them advertised keys the spec never defines - log a warning when a legacy URI has no TLD registered, so a taglibs upgrade that renames one is observable instead of silently dropping the alias - drop the unreachable null-checks in permitJakartaTagsUris(); ValidatorXml always has init params and the permittedTaglibs TLD always has a validator - scope the PMD suppression to the pasted data block so the hand-written methods are analysed again - cover scanPlatform() forwarding the aliases into the per-deployment map
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Registers the seven Jakarta Tags 3.0 taglib URIs (
jakarta.tags.core,.fmt,.sql,.xml,.functions,.permittedTaglibs,.scriptfree) so JSP pages can actually use them.Why
Jakarta Tags 3.0 renamed the JSTL taglib URIs from the legacy
http://java.sun.com/jsp/jstl/*form to the shortjakarta.tags.*form.The taglibs-standard implementation we shade in
deps/taglibs-shadepredates that rename. The shade only rewrites bytecode (javax.servlet→jakarta.servlet); it does not touch the TLD descriptors, so the shipped TLDs still declare the legacy URIs only. Confirmed by inspecting the jar — none of its 12 TLDs contains ajakarta.tags.*URI.The result is that any page containing
fails at JSP compile time. This breaks the entire Jakarta Tags 3.0 TCK, and the EJB Lite JSP vehicles as a side effect since their shared harness imports the same URI.
How
TomEETldScanneralready pre-populates the TLD cache with the container's own taglibs so they don't have to be parsed on every deployment. This adds the Jakarta Tags URIs as additional keys for those same resources, plus widens thepermittedTaglibsvalidator so a page guarded by that TLV may use either spelling.Two details worth a reviewer's attention:
TldResourcePathinstance rather than constructing new ones.scanPlatform()tells myfaces and jstl entries apart by reference identity on the resource path's URL, andTLD_RESOURCE_TAG_LIBis keyed on it. Both are load-bearing and commented in the code.JSTL_URL == null), degrading to normal scanning rather than failing.I also corrected the class-level comment. It claimed the file is "generated so we don't really care", which is misleading: there is no generator in the build. The data was dumped once by the
sysout()method kept commented out at the bottom of the same file and pasted in, and the file has been hand-edited several times since. Thatsysout()is itself stale — it still recognises JSTL entries by thetaglibs-standard-jstleljar name whereas the shipped jar istaglibs-shade-*.jar— so it can no longer reproduce the file. The new comment says so.Considered and rejected
Switching to a Jakarta-native implementation (
org.glassfish.web:jakarta.servlet.jsp.jstl:3.0.1) would be the more principled fix — it ships both namespaces, keeps the sameorg.apache.taglibs.standard.*packages, and self-shades Xalan. Apache Taglibs itself never released a Jakarta version (1.2.5 is still latest), which is why the shade exists at all. But the swap touches ~40 sites across BOMs, assembly descriptors,jarsToSkippatterns and jar-name filters, so it does not belong in a bug fix. Probably worth its own issue.Testing
Unit tests in
TomEETldScannerJakartaTagsTestcover the alias mapping, legacy URIs still resolving, the validator widening, idempotency, and the no-JSTL no-op. Note these drive the aliasing against a synthetic resource map via reflection, because the shaded taglibs jar is not on that module's test classpath.The real proof is the TCK. Built the plume distro, confirmed the fix is in the shipped
tomee-catalinajar, and ran the Jakarta EE 11 Web Profile TCKtagspartition from apache/tomee-tck with the exclusion lifted:ClientEjblitejspTestgreenThe shipped jar's
c.tldstill declares only<uri>http://java.sun.com/jsp/jstl/core</uri>, so the fact thatjakarta.tags.corepages now compile can only come from this change.The 8 classes still failing are unrelated to TLD registration: the five
sql/*classes and the compatibility class hitSQLSyntaxErrorException: Table/View 'JSTL_TAB1' does not exist(the harness never creates those Derby tables), andxmlcore.parse/xtransform.transformfail resolving an external systemId. A matching tomee-tck change narrowsexclusions/tags.txtto just those.🤖 Generated with Claude Code