I've created an application with an external dependency that registers WABs. The WABs are created with a manifest.mf that contains the desired Web-ContextPath: '/custom/route' configuration. This works to register a new context and serve it's contents on that path. However with the move from pax web 7 to 8 that new context that's created now creates pathing conflicts with servlets under the same base URI. example servlet under /custom/route/myservlet can never be reached because the path match will grab the /custom/route context and my servlet isn't registered to that context. Those outside dependencies can change their path and I'd prefer to not have to register to those outside contexts. I've tried creating my own context to match i.e. create a new servletcontexthelper with the path /custom/route but then my servlets cannot be found ( presumably the precedence of the context created by the WAB wins out ).
So I've tried a lot of different solution at this point but they all don't work for one reason or another.
Can those WABs be registered under the default context (thus making the path matching work for the wab and servlets)? I've tried this with a DefaultServlet but then the resources aren't being served. Or is there a way to have the servlets take priority on the path matching even with the WABs being on their /custom/route context?
I've created an application with an external dependency that registers WABs. The WABs are created with a manifest.mf that contains the desired Web-ContextPath: '/custom/route' configuration. This works to register a new context and serve it's contents on that path. However with the move from pax web 7 to 8 that new context that's created now creates pathing conflicts with servlets under the same base URI. example servlet under /custom/route/myservlet can never be reached because the path match will grab the /custom/route context and my servlet isn't registered to that context. Those outside dependencies can change their path and I'd prefer to not have to register to those outside contexts. I've tried creating my own context to match i.e. create a new servletcontexthelper with the path /custom/route but then my servlets cannot be found ( presumably the precedence of the context created by the WAB wins out ).
So I've tried a lot of different solution at this point but they all don't work for one reason or another.
Can those WABs be registered under the default context (thus making the path matching work for the wab and servlets)? I've tried this with a DefaultServlet but then the resources aren't being served. Or is there a way to have the servlets take priority on the path matching even with the WABs being on their /custom/route context?
Share Improve this question asked Mar 21 at 20:45 SteveSteve 1511 gold badge1 silver badge7 bronze badges 1- This deserves serious explanation, which I'll provide later. For now: 1) be sure I'll explain it on Monday, 2) Pax Web 8 is huge refactoring of Pax Web 7 and much more OSGi CMPN compliant, 3) there's one big violation of the spec and it it exactly the one you see - WABs "take over" contexts - the reason is however Servlet API specification which IMO is more important than OSGi CMPN. – Grzegorz Grzybek Commented Mar 22 at 7:32
1 Answer
Reset to default 1Some justification at code level is provided here:
- https://github/ops4j/.ops4j.pax.web/issues/1725
- https://github/ops4j/.ops4j.pax.web/commit/b6cf8baa12abcd0c443c6d8430c0964e6cefe3e9
Let me clarify the issue you're seeing. You have a Web Application Bundle (as defined by OSGi CMPN Web Applications specification) with:
Web-ContextPath: /custom/route
header in META-INF/MANIFEST.MF
.
At the same time you have a servlet mapped to /custom/route/myservlet
URI (prefix mapping).
The problem here is that there are two worlds of Java web specifications:
- Jakarta Servlet API - the specification that made Java an Enterprise-grade technology and ecosystem
- 3 OSGi CMPN specification:
- Chapter 102 - HttpService
- Chapter 128 - Web Applications
- Chapter 140 - Http Whiteboard
While OSGi web specifications are based on Servlet API, there's one clear difference:
- Servlet API defines mapping URIs to components in a way, that the longest prefix path is matched against available contexts (you can think about context as single web application - like single WAR archive dropped to Tomcat's
webapps
directory) - OSGi specification (particularly the Whiteboard specification, section 140.2 The Servlet Context) allows kind of cross matching - if a URI is first matched to some context and there's no internal component (like servlet) in this context, shorter context is matched.
So if you have two contexts:
/my/context
/my
And you have URI /my/context/someServlet
, then under Servlet API, if there's no /someServlet
mapping in /my/context
, there's no attempt to find a servlet mapped to /context/someServlet
under /my
context. However this is not true in OSGi Whiteboard specification.
Because Pax Web puts emphasis on using real Servlet containers (Jetty, Tomcat, Undertow), I decided to explicitly violate OSGi CMPN 140 Whiteboard specification to be more compliant with Servlet API specification. Mind that Felix HTTP implementation of the same OSGi specifications is based on single dispatcher servlet registered under single context in Jetty - this gives you more freedom and less benefits from underlying Servlet container.
There's however a way to make your scenario work. Instead of having:
- WAB with
/custom/route
context - Servlet mapped to
/custom/route/myservlet
path under (implicit here!)/
_context
you should have:
- WAB with
/custom/route
context - Servlet mapped to
/myservlet
path under (explicit here!)/custom/route
_context
While it seems that you have to put your servlet into your WAB, you can actually have the servlet registered to some other existing context (whether it's a context from existing WAB or other Whiteboard component).
So your servlet has to be registered with these OSGi Service properties:
osgi.http.whiteboard.servlet.pattern=/myservlet
- for servlet mapping within some contextosgi.http.whiteboard.context.select=(osgi.http.whiteboard.context.path=/custom/route)
- to tell Pax Web that this servlet has to be registered withinServletContextHelper
mapped to/custom/route
context path
Remember - with Whiteboard, if you don't specify osgi.http.whiteboard.context.select
property, it defaults to osgi.http.whiteboard.context.select=(osgi.http.whiteboard.context.name=default)
which is usually a kind of implicit context with /
path.
See this Pax Web integration tests where WAB and Whiteboard are mixed together.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744334011a4569025.html
评论列表(0条)