Hello

Actually it is a good time to give you a hint about the new "context"
organization in Pax Web. I'll try to be concise.

Fundamentally a "context" is a container-specific implementation of
javax.servlet.ServletContext and maps 1:1 with a "context path" ("/",
"/my-context" or any name that stems from the WAR base name you drop to
Tomcat/Jetty/Wildfly/...).

In OSGi CMPN Whiteboard Service spec, a "context" is represented by a name
referring to some (possibly default) implementation of
org.osgi.service.http.context.ServletContextHelper.
In OSGi CMPN Http Service spec, a "context" is the object (default if null)
you pass to HttpService.registerServlet(..., httpContext), but in Pax Web,
internally it is treated (after some adjustments) as ServletContextHelper.

Because according to Whiteboard specification,
org.osgi.service.http.context.ServletContextHelper may be
whiteboard-registered as OSGi service, it has to be "customized" by some
service tracker - so Pax Web 8 has something called
org.ops4j.pax.web.service.spi.model.OsgiContextModel. This is an object
used to represent org.osgi.service.http.HttpContext and
org.osgi.service.http.context.ServletContextHelper internally.

There are FOUR trackers that take incoming service and customize it to
org.ops4j.pax.web.service.spi.model.OsgiContextModel (names should given
you a hint about "incoming" object):
 -
org.ops4j.pax.web.extender.whiteboard.internal.tracker.legacy.HttpContextMappingTracker
("legacy" Pax Web Whiteboard)
 -
org.ops4j.pax.web.extender.whiteboard.internal.tracker.HttpContextTracker
(Pax Web Whiteboard to track objects not designed (by the spec) to be
registered as services)
 -
org.ops4j.pax.web.extender.whiteboard.internal.tracker.legacy.ServletContextHelperMappingTracker
("legacy" Pax Web Whiteboard for standard ServletContextHelper)
 -
org.ops4j.pax.web.extender.whiteboard.internal.tracker.ServletContextHelperTracker
(THE tracker to track standard Whiteboard
org.osgi.service.http.context.ServletContextHelper servlces)

So all the web elements (servlets, filters, listeners, error pages, welcome
files, ...) are registered "in association" with one OR MORE (and this
"more" is something that was fundamentally missing in Pax Web 7)
org.ops4j.pax.web.service.spi.model.OsgiContextModel.

Now the connection with Jetty/Tomcat/Undertow. Because user may register
many ServletContextHelper services with different (or same) value for
"osgi.http.whiteboard.context.path" service property, we may have this tree
of related objects:

Jetty/Tomcat/Undertow implementation of javax.servlet.ServletContext for
"/" context path
|
+-- org.ops4j.pax.web.service.spi.model.OsgiContextModel 1a
+-- org.ops4j.pax.web.service.spi.model.OsgiContextModel 2a with a bit
lower ranking
+-- ...

Jetty/Tomcat/Undertow implementation of javax.servlet.ServletContext for
"/some" context path
|
+-- org.ops4j.pax.web.service.spi.model.OsgiContextModel 1b
+-- org.ops4j.pax.web.service.spi.model.OsgiContextModel 2b with a bit
lower ranking
+-- ...

Of course of you simply modify a registration of already registered
ServletContextHelper (customized by trackers into OsgiContextModel by
changing its ranking, the above relations may change and different
OsgiContextModel will be "effective" for given container-specific context.

Of course you can imagine that you change not the ranking but
"osgi.http.whiteboard.context.path" property (say from "/" to "/path") -
this can (should, according to Whiteboard spec) re-register already
registered servlets, so they may "switch" from being mapped under
"/servlet-mapping" to being mapped under "/path/servlet-mapping"... That's
already implemented ;)

Also, according to "140.2.7 Relation to the Servlet Container", servlets
(and filters) should see such "ServletContext" that when they call
"getResource()" on it, they'll get (by default) resources from the bundle
that registered given context (nothing similar to such behavior in Pax Web
7). Also we can have many servlets registered to the same "context", but
using different bundles - they should NOT be able to "getResource()" from a
wrong bundle!

Finally org.ops4j.pax.web.service.spi.servlet.OsgiServletContext IS an
implementation of javax.servlet.ServletContext that does exactly this -
wrap actual container-specific ServletContext and implement some methods
according to Whiteboard spec.

Of course "addServlet()" throws (in Whiteboard specification)
UnsupportedOperationException.

But fortunately I have all the pieces ready to properly (despite the
specification) register a servlet/filter/listener from
ServletContainerInitializer - EXACTLY as if they were registered through
Whiteboard (with validation and default service ranking) - so existing
mechanisms will be used - such servlets can easily be wrapped with
Whiteboard filters and will integrate with what I've already refactored.

So please give me a little more time! I don't want to sacrifice great work
others already did (Achim, Mark, Guillaume, JBO, Stephan, Harald and others
from https://github.com/ops4j/org.ops4j.pax.web/graphs/contributors) to
make Pax Web OSGi CMPN Whiteboard compliant. I don't want to lose JSP, JSF
support and I don't want to implement everything in a single "dispatcher
servlet" because native containers should be leveraged to the widest extent.

best regards
Grzegorz Grzybek

czw., 20 sie 2020 o 15:34 Grzegorz Grzybek <gr.grzy...@gmail.com>
napisaƂ(a):

> Hello
>
> If you look at the attached table, you'll see what's already implemented
> and what yet has to be done. From Whiteboard point of view, I'm almost
> there, because These are already tracked:
>  - servlets
>  - filters
>  - listeners
>  - resources (which are internally servlets)
>  - contexts (ServletContextHelper)
>  - error pages (as registration parameters of servlets)
>
> As you know, the strength of Pax Web is that it tracks more. These are
> implemented:
>  - welcome files (whew - that was tricky - OSGi CMPN Whiteboard spec
> doesn't make it easy to implement it)
>  - error pages (as separate objects)
>
> Also, WebContainer (an extension of org.osgi.service.http.HttpService)
> also allows to register additional "web elements" and I'm in the process of
> implementing everything that's mentioned in the table.
>
> However, I've just found a really nasty obstacle... See 140.2.6 Behavior
> of the Servlet Context
> <https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.http.whiteboard.html#d0e119708>
> :
>
> addServlet(...) | 3.0 | Throws UnsupportedOperationException.
>
> OSGi CMPN Whiteboard spec:
>  - didn't care about the dynamism and dynamic registration of
> Servlets/Filters/Listeners
>  - didn't care about something like
> javax.servlet.ServletContainerInitializer (and JSPs, which are a bit
> related in terms of their configuration).
>  - has very strict (and already carefully implemented) separation of
> "physical ServletContexts" from "OSGi ServletContexts". See "140.2 The
> Servlet Context":
>
> In the case of two Servlet Context Helpers with the same path, the service
> with the highest ranking is searched first for a match. In the case of a
> tie, the lowest service ID is searched first.
>
> So - each registered ServletContextHelper should actually be implemented
> as a separate ServletContext which delegates to a single (by contextPath)
> container-specific ServletContext. It's about attribute separation, session
> separation, classloader separation and security handling. I spent most of
> my refactoring to implement this behavior correctly and it's presented in
> "140.2.7 Relation to the Servlet Container":
>
> [image: image.png]
>
> So, what's the problem? If some ServletContainerInitializer (like
> org.apache.myfaces.ee6.MyFacesContainerInitializer) is used (it works now
> in Pax Web 7, because Pax Web 7 doesn't do the above delegation), it calls:
>
> // the FacesServlet is not installed yet - install it
> ServletRegistration.Dynamic servlet =
> servletContext.addServlet(FACES_SERVLET_NAME, FACES_SERVLET_CLASS);
>
> And according to OSGi CMPN Whiteboard spec, it should simply throw
> UnsupportedOperationException (bye, bye TCK compliance).
>
> I of course don't care much about such flaws in specification and I really
> want to implement this (allow JSF to work in Pax Web 8). But I have to
> spend a bit more time with dynamic registration of servlets and filters -
> especially because current HttpService/WebContainer/Whiteboard registration
> is already working great (with all the service ranking shadowing).
>
> In other words - a servlet registered by some 3rd party customizer, should
> integrate well with what we already have. It should be able to shadow such
> servlet (by registering one with higher ranking and same name/patterns), it
> should be able to register a filter to it (or a preprocessor), it should
> (?) be possible visible through HttpRuntime service (DTOs).
>
> This problem was revealed when I was bringing back JSP support (which
> again is not covered by OSGi CMPN). So I have to work on it more (support
> is always welcomed!).
>
> We could also think about releasing Pax Web 8 with ready (it really is!)
> implementation of R7 Whiteboard spec only, but this would be a much trimmed
> down version of the Pax Web we know...
>
> Here's the current state of implementation (sorry if it formats badly).
> "no" means it is not and will not be implemented. Empty cell means the
> implementation is still in progress.
>
> [image: image.png]
>
> best regards
> Grzegorz Grzybek
>
>

Reply via email to