You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Split out of #1110, which covers the upstream imports that already have a fork class of the same name. This one is about the upstream classes that have no fork equivalent and that reach javax.servlet-bound code. The failure mode is different: not a branch that quietly does nothing, but NoClassDefFoundError at the first call.
javax.servlet is not on the classpath
org.openidentityplatform.openam.click exists so the framework could run under Jakarta. The deployment resolves only jakarta.servlet-api-5.0.0; none of the 381 jars on the openam-server-only classpath carries javax/servlet/http/HttpServlet.class, and there is no javax.servlet-api anywhere in either module.
Upstream Click 2.3.0 is compiled against javax.servlet. Disassembling click-nodeps-2.3.0.jar:
So any entry into upstream Click's Context-dependent code fails twice over: the upstream Context keeps its own thread local, which nothing populates because only the fork's servlet is mapped; and the javax.servlet types it hands back do not exist at runtime.
Where the fork calls into it
ClickUtils.getLogService() — 7 call sites
util/ContainerUtils.java:117, :140, :238, :264 (copyContainerToObject(), copyObjectToContainer()), :1053, :1089 (copyFieldsToMap(), copyMapToFields()), and util/ClickUtils.java:530 in the fork's own ClickUtils.
All of them call org.apache.click.util.ClickUtils.getLogService().
The fix is local and the fork already uses the correct pattern two places away — util/ClickUtils.java:1540:
Page.java:170 declares protected Format format, with getFormat()/setFormat() at :484/:493; service/XmlConfigService.java:178 holds Class<? extends Format> formatClass and :386createFormat() instantiates it, defaulting to org.apache.click.util.Format at :1524.
A Format instance is created per page and exposed to templates as $format. Its getLocale(), url() and date() all go through Context.getThreadLocalContext().
org.apache.click.util.MessagesMap
service/DefaultMessagesMapService.java:65 returns new MessagesMap(baseClass, globalResource, locale) — the upstream class. ClickServlet.java:1600 calls page.getMessages() on every request, so one of these is constructed per request.
Construction survives only by accident: the three-argument constructor does not touch Context, while ensureInitialized() — which does Context.getThreadLocalContext().getServletContext() — runs on the first get().
How close this is to firing
Nothing triggers it today, and the margin is thin.
No shipped .htm template dereferences $format or $messages, so MessagesMap.ensureInitialized() and every Format method stay uncalled. A single $messages.someKey in any configurator template would turn every request into a hard failure.
ErrorPage.onInit() does build an ErrorReport on every error, but click.xml runs in <mode value="production"/> and the shipped click/error.htm is a static page that never dereferences $errorReport.
Suggested fix
Replace the 7 org.apache.click.util.ClickUtils.getLogService() calls with the fork's own getConfigService(...).getLogService(). Cheapest change, removes the sharpest edge.
Fork org.apache.click.util.Format and org.apache.click.util.MessagesMap, or drop them and use fork-local equivalents. Both are small and neither needs javax.servlet other than through Context, which the fork already has.
Audit the remaining upstream classes with no fork twin for the same dependency. PropertyUtils, RequestTypeConverter and HtmlStringBuffer were checked and carry no reference to Context, ConfigService or javax.servlet, so they are safe to keep using as-is.
Removing org.apache.click:click-nodeps:2.3.0 altogether is the end state, tracked as the closing step of #1110.
Split out of #1110, which covers the upstream imports that already have a fork class of the same name. This one is about the upstream classes that have no fork equivalent and that reach
javax.servlet-bound code. The failure mode is different: not a branch that quietly does nothing, butNoClassDefFoundErrorat the first call.javax.servletis not on the classpathorg.openidentityplatform.openam.clickexists so the framework could run under Jakarta. The deployment resolves onlyjakarta.servlet-api-5.0.0; none of the 381 jars on theopenam-server-onlyclasspath carriesjavax/servlet/http/HttpServlet.class, and there is nojavax.servlet-apianywhere in either module.Upstream Click 2.3.0 is compiled against
javax.servlet. Disassemblingclick-nodeps-2.3.0.jar:So any entry into upstream Click's
Context-dependent code fails twice over: the upstreamContextkeeps its own thread local, which nothing populates because only the fork's servlet is mapped; and thejavax.servlettypes it hands back do not exist at runtime.Where the fork calls into it
ClickUtils.getLogService()— 7 call sitesutil/ContainerUtils.java:117,:140,:238,:264(copyContainerToObject(),copyObjectToContainer()),:1053,:1089(copyFieldsToMap(),copyMapToFields()), andutil/ClickUtils.java:530in the fork's ownClickUtils.All of them call
org.apache.click.util.ClickUtils.getLogService().The fix is local and the fork already uses the correct pattern two places away —
util/ClickUtils.java:1540:and
:907:org.apache.click.util.FormatPage.java:170declaresprotected Format format, withgetFormat()/setFormat()at:484/:493;service/XmlConfigService.java:178holdsClass<? extends Format> formatClassand:386createFormat()instantiates it, defaulting toorg.apache.click.util.Formatat:1524.A
Formatinstance is created per page and exposed to templates as$format. ItsgetLocale(),url()anddate()all go throughContext.getThreadLocalContext().org.apache.click.util.MessagesMapservice/DefaultMessagesMapService.java:65returnsnew MessagesMap(baseClass, globalResource, locale)— the upstream class.ClickServlet.java:1600callspage.getMessages()on every request, so one of these is constructed per request.Construction survives only by accident: the three-argument constructor does not touch
Context, whileensureInitialized()— which doesContext.getThreadLocalContext().getServletContext()— runs on the firstget().How close this is to firing
Nothing triggers it today, and the margin is thin.
.htmtemplate dereferences$formator$messages, soMessagesMap.ensureInitialized()and everyFormatmethod stay uncalled. A single$messages.someKeyin any configurator template would turn every request into a hard failure.ContainerUtilscopy methods are only reachable from a ClickForm, and noFormis constructed anywhere in the product (see Remove the Java serialization round trip from the bundled Click HiddenField #1109).ErrorPage.onInit()does build anErrorReporton every error, butclick.xmlruns in<mode value="production"/>and the shippedclick/error.htmis a static page that never dereferences$errorReport.Suggested fix
org.apache.click.util.ClickUtils.getLogService()calls with the fork's owngetConfigService(...).getLogService(). Cheapest change, removes the sharpest edge.org.apache.click.util.Formatandorg.apache.click.util.MessagesMap, or drop them and use fork-local equivalents. Both are small and neither needsjavax.servletother than throughContext, which the fork already has.PropertyUtils,RequestTypeConverterandHtmlStringBufferwere checked and carry no reference toContext,ConfigServiceorjavax.servlet, so they are safe to keep using as-is.Removing
org.apache.click:click-nodeps:2.3.0altogether is the end state, tracked as the closing step of #1110.