I need some precision about the ServletContextHelper behavior related to the Http Whiteboard Specification when multiple bundle use the same ServletContextHelper
The spec says :
The Http Whiteboard implementation must create a separate ServletContext instance for each ServletContextHelper service. Whiteboard services can be associated with the Servlet Context Helper by using the osgi.http.whiteboard.context.select property. If this property is not set, the default Servlet Context Helper is used.
If I understand correctly, all Servlet or Filter using the same ServletContextHelper reference are bound to the same 'ServletContext'
Then :
Some implementations of the ServletContextHelper may be implemented using a Service Factory, for example to provide resources from the associated bundle, as the default implementation does. Therefore the Whiteboard implementation must get the Servlet Context Helper using the Bundle Context of the bundle that registered the Whiteboard service.
So if a bundle A registers a Servlet with the ServletContextHelper X, and the bundle B registers a Filter with the same reference of ServletContextHelper, then the Servlet and Filter are registered to the same ServletContext, but their init methods are called with two different instances of ServletContext (in order to implements the getClassLoader() methods differently) ?
Moreover, what is the behavior of the "default" ServletContextHelper ? is there always a "default" ServletContextHelper registered ? is it shared between bundles or is there only one instance by bundles ?
I work on Pax Web 8, where I really want to get the behavior right.
140.2.7 Relation to the Servlet Container chapter of OSGi CMPN specification shows a picture, where there are actually three layers of javax.servlet.ServletContext
objects:
ServletContext
implementation specific to real Servlet container. In Pax Web it's one of:
org.eclipse.jetty.servlet.ServletContextHandler.Context
org.apache.catalina.core.ApplicationContext
io.undertow.servlet.spec.ServletContextImpl
ServletContext
implementation in 1:1 relation with the org.osgi.service.http.context.ServletContextHelper
OSGi serviceServletContext
that's implementing the service-factory contract for each Whiteboard bundle where all but getClassLoader()
methods delegate to the above SCH and getClassLoader()
returns bundle.adapt(BundleWiring.class).getClassLoader()
The problem is related to the double-responsibility principle assumed with org.osgi.service.http.context.ServletContextHelper
. It is used both to implement functional aspects (handleSecurity()
) and resource-separation aspects (getResource()
).
So you're right - if Bundle A registers a servlet and Bundle B registers a filter, both will use the same instance of ServletContext (supported by the referenced ServletContextHelper), but their init()
methods will be provided with different, bundle-specific instance of ServletContext
.
This is simply implemented by delegation, there are two implementations:
org.ops4j.pax.web.service.spi.servlet.OsgiServletContext
implements the 1:1 behaviororg.ops4j.pax.web.service.spi.servlet.OsgiScopedServletContext
implements getClassLoader()
and delegates all other methods to the above OsgiServletContext