eclipse-ee4j / eclipse-ee4j/krazo
Krazo does not work with OpenLiberty 22.* beta (Jakarta EE 10)
- Dominant language
- Java
- Stars
- 55
- Forks
- 25
- Avg merge
- 3h 25m
- Merged PRs (30d)
- 3
Description
Recently, I was experimenting with Krazo 3.0.1 on Jakarta EE 10, using OpenLiberty 22.0.0.13-beta. I stumbled upon the same error message as reported in #282. I thought it had been resolved with #288, so I checked if the `LibertyHttpCommunicationUnwrapper` got invoked - it did.
So I dug a little further to find the [`ServletUtil#unwrapRequest`](https://github.com/OpenLiberty/open-liberty/blob/366d74a582a310dacd6a51eb3bd8a71109e8c0b6/dev/com.ibm.ws.webcontainer/src/com/ibm/wsspi/webcontainer/util/ServletUtil.java#L64) method of OpenLiberty. As pointed out by @jesse-gallagher in #282, Liberty expects to be able to get an instance of their `IExtendedRequest` type from the passed-in request object. The passed-in request object (supplied by Krazo) is a `HttpServletRequestWrapper` instance backed by a Weld proxy for an [`SRTServletRequest60`](https://github.com/OpenLiberty/open-liberty/blob/366d74a582a310dacd6a51eb3bd8a71109e8c0b6/dev/io.openliberty.webcontainer.servlet.6.0.internal/src/io/openliberty/webcontainer60/srt/SRTServletRequest60.java#L27) instance. The `unwrapRequest` method doesn't handle this object properly, and hence throws the "**SRV.8.2: RequestWrapper objects must extend ServletRequestWrapper or HttpServletRequestWrapper**".
(Aside) the `SRTServletRequest60` does in fact implement the `IExtendedRequest` interface. I think the `isInstance()` check in Liberty fails due to the Weld proxy around it. I've logged an issue for that: https://github.com/OpenLiberty/open-liberty/issues/23774.
Anyway, when Krazo invokes `RequestDispatcher#forward` from [`ServletViewEngine#forwardRequest()`](https://github.com/eclipse-ee4j/krazo/blob/master/core/src/main/java/org/eclipse/krazo/engine/ServletViewEngine.java#L121), it passes a `HttpServletRequestWrapper` instance that wraps "the original request". That "original request" comes from the `ViewEngineContext`, which was constructed by the [`ViewableWriter`](https://github.com/eclipse-ee4j/krazo/blob/master/core/src/main/java/org/eclipse/krazo/core/ViewableWriter.java#L159). The `ViewableWriter` in turn gets it `@Inject`-ed, which explains the Weld proxy.
In my own experiment, I could work around this by implementing a `WeldHttpCommunicationUnwrapper`, which works pretty much the same as the existing [`LibertyHttpCommunicationUnwrapper`](https://github.com/eclipse-ee4j/krazo/blob/master/resteasy/src/main/java/org/eclipse/krazo/resteasy/core/LibertyHttpCommunicationUnwrapper.java). Using reflection, it checks if the request implements [`WeldClientProxy`](https://github.com/weld/api/blob/master/weld/src/main/java/org/jboss/weld/proxy/WeldClientProxy.java). If so, it invokes `WeldClientProxy#getMetadata()` and then `WeldClientProxy.Metadata#getContextualInstance()` to get the actual `SRTServletRequest60` instance.
Would you be interested in having this in Krazo's code base?
Contributor guide
Assessment
This issue has not been assessed yet.