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]

Reply via email to