[#1111] Click fork: stop calling javax.servlet-bound upstream ClickUtils - #1112
Conversation
…und upstream ClickUtils The fork is compiled against jakarta.servlet, but click-nodeps 2.3.0 is not: upstream ClickUtils.getLogService() resolves a javax.servlet.Servlet- Context that is absent from the classpath, and reads a thread local that only the upstream servlet populates. Route these calls to the fork's own ClickUtils.getLogService() instead. ContainerUtils imported org.apache.click.util.ClickUtils, shadowing the same-package fork class, so its unqualified call resolved upstream too. Its LogService import is repointed as well: the upstream interface is javax.servlet-bound via onInit(ServletContext). No behaviour change; nothing reaches this code today.
Code reviewReviewed the diff, compiled 1. The sweep is incomplete in the file it edits —
|
…ContainerUtils, ClickUtils, ErrorReport ErrorReport fully-qualified org.apache.click.util.ClickUtils at seven sites. Unlike the rest, it is reachable (ErrorPage, VelocityTemplateService), so the fork kept a hard reference into the javax.servlet-compiled jar in live code. De-qualified onto the fork's own getBundle/escapeHtml. ContainerUtils imported upstream Button and Label, which extend upstream Field, so every instanceof filter was permanently false for fork controls. Repointed. FieldSet has no fork equivalent, so its guard was always true and is dropped. ClickUtils imported upstream ActionLink, making the getCssSelector branch at :1461 dead for every control the fork can produce. getConfigService's failure message told operators to register org.apache.click.ClickServlet, which never sets the fork's ConfigService attribute -- following it made the failure permanent.
|
Fixed items 1, 3, 4 and 7 in 21c3743; description corrected for item 2. Notes on what I verified, and two places where the picture turned out different. 4 — The finding was right, but "those two methods happen to be servlet-free today, which is the only reason it works" doesn't hold: it wasn't working. Upstream
The allowlist needs correcting before #1110 uses it. Same probe:
1 — control imports. Fixed: One correction on the consequences. Nothing instantiates a fork 2 —
3 — 7 — diagnostic. Fixed, and it was worse than stated: 5 and 6 — not taken. Correct readings, but Still open, found while verifying the above — logging rather than fixing here: Build-time guard. Agreed, and this exchange is the argument for it — careful manual inspection produced an allowlist that was wrong on three of four entries. It will be handled as part of #1110. Verification is bytecode plus the probe above, since the fork has no tests: |
vharseko
left a comment
There was a problem hiding this comment.
Approving.
Items 1, 3, 4 and 7 are fixed in 21c3743, and the corrections to my readings are accepted: the Button/Label repoint was latent rather than live (nothing instantiates a fork Form, and TemplatedForm extends the upstream one), the getResourceAsStream anchor swap is harmless because the absolute names resolve through the shared webapp classloader and :1573's relative names never reach the anchor at all, and the FieldSet removal is type-safe. ErrorReport turning out to be a link-time NoClassDefFoundError rather than a latent hazard makes the case for the PR on its own; thanks for the probe.
Three small things left, none blocking:
-
AbstractLink.java:539—isAjaxTarget()still resolvesACTION_LINKthroughimport org.apache.click.control.ActionLink(line 24). Invisible to thejavapcheck, because javac inlines compile-time String constants and both copies are"actionLink"today — so there is no reference in the bytecode and no linkage error, but the fork's constant and the value actually matched are no longer tied together. One for the same open list asPropertyUtilsatContainerUtils:272, theHtmlStringBufferimports andForm.java:3061— or for the #1110 guard, if that lands first. -
ErrorReport.java— missing thePortions Copyrighted 2026 3A Systems, LLCline thatClickUtils.java:18andContainerUtils.java:18both carry. -
PR description — still reads "No behaviour change; nothing reaches this code today". The update mentioned in the reply doesn't appear to have landed, and that sentence is what ends up in the merge commit.
The fork is compiled against jakarta.servlet, but click-nodeps 2.3.0 is not: upstream ClickUtils.getLogService() resolves a javax.servlet.Servlet- Context that is absent from the classpath, and reads a thread local that only the upstream servlet populates. Route these calls to the fork's own ClickUtils.getLogService() instead.
ContainerUtils imported org.apache.click.util.ClickUtils, shadowing the same-package fork class, so its unqualified call resolved upstream too. Its LogService import is repointed as well: the upstream interface is javax.servlet-bound via onInit(ServletContext).
No behaviour change; nothing reaches this code today.
fixes #1111 issue