kbachl opened a new issue, #1653:
URL: https://github.com/apache/wicket/issues/1653
# ListenerRequestHandler.detach() can trigger rendering callbacks after the
response has been flushed
## Description
We observed HTTP session creation during request detachment, after the
response had already been committed. Consequently, the servlet container could
not send the session cookie and logged `SESN0066E` and `SRVE8114W`.
The production stack trace identifies Wicket’s collection of listener log
data as the entry point.
## Environment
- **Wicket:** 10.11.0
- **Application server:** Open Liberty 26.0.0.10 (from 25.0.0.1+ onwards
seen)
- **Platform:** Jakarta EE 11 / Servlet 6.1
- **CDI implementation:** Weld 6.0.2
- **Production JDK:** OpenJDK 25.0.4
- **Isolated reproduction JDK:** 27
## Relevant code path
In Wicket 10.11.0:
1. `WicketFilter.processRequestCycle()` processes the request, flushes the
response, and subsequently calls `requestCycle.detach()` in its `finally` block.
2. `ListenerRequestHandler.detach()` constructs `ListenerLogData` before
detaching the page/component provider.
3. `ListenerLogData` calls `pageAndComponentProvider.getComponent()` to
obtain component metadata.
4. If the component cannot be found on a stateless page,
`PageAndComponentProvider.getComponent()` calls `internalInitialize()` and
`beforeRender()` to allow lifecycle callbacks to create the component.
5. These callbacks therefore run during detachment, after the response flush.
In our application, this reaches a component’s `onConfigure()`, which checks
the login state through a CDI `@SessionScoped` bean. Resolving the bean causes
the container to create an HTTP session.
## Production stack trace
Abbreviated stack, with the innermost call first:
```text
SessionManager.createSession()
...
SessionHolder.getSession()
LazySessionBeanStore.getSession()
...
KontoBean$WeldClientProxy.isLoggedIn()
AccountHeader2017.onConfigure(AccountHeader2017.java:46)
Component.configure(Component.java:996)
...
Component.beforeRender(Component.java:949)
PageAndComponentProvider.getComponent(PageAndComponentProvider.java:176)
ListenerLogData.lambda$new$0(ListenerLogData.java:54)
PageLogData.optional(PageLogData.java:63)
ListenerLogData.<init>(ListenerLogData.java:54)
ListenerRequestHandler.detach(ListenerRequestHandler.java:128)
...
WicketFilter.processRequestCycle(WicketFilter.java:285)
```
## Isolated reproduction
Using `BaseWicketTester`:
1. Create a bookmarkable stateless page.
2. Create a `PageAndComponentProvider` pointing to a missing component.
3. Create a `ListenerRequestHandler` using that provider.
4. Disable the request logger.
5. Call `handler.detach()` and count `onBeforeRender()` invocations.
### Results
| Case | `onBeforeRender()` calls during detach |
| --- | ---: |
| Missing component, stateless page, request logger disabled | 2 |
| Existing component, stateless page | 0 |
| Missing component, stateful page | 0 |
| Component created and resolved before detach | 0 |
This reproduces the lifecycle behavior without Brix or application code.
### Scope of the reproduction
The isolated test calls `detach()` directly. It does not reproduce the
complete Liberty/CDI request or an actual HTTP response commit.
The cookie failure is evidenced separately by the production FFDC stack. The
original triggering request URL is unavailable.
## Additional observations
Disabling request logging does not prevent the behavior:
`ListenerRequestHandler.detach()` constructs the log data independently of that
setting.
`PageLogData.optional()` catches lookup exceptions but cannot prevent the
lifecycle side effects caused by `getComponent()`.
## Expected behavior
Collecting diagnostic metadata during detachment should not initialize
components or invoke rendering callbacks. An unresolved component should yield
incomplete/null log metadata while cleanup still proceeds.
A fix should preserve normal component resolution during request processing,
including components legitimately created in lifecycle callbacks, while
avoiding that resolution as a side effect of log-data collection after response
flush.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]