Ultimately this seems like a bug.
But ...
The origin of the final ultimate "descriptor" is a complicated mess in the servlet spec, that includes a combination of all of the following ...
- various javax.servlet annotations
- web fragments in WEB-INF/lib
- the WEB-INF/web.xml
The order of which these load is also further complicated by the fact that the various XML based ones can specify the order of the resolution of the other ones.
Then, Jetty has a few other ways, on top of the servlet spec, to set the descriptor too.
- the default descriptor (webdefault.xml)
- any manually entered ones from the WebAppContext
- (all of the webapp internal descriptors from above)
- the override descriptor
This order is fairly consistent and predictable, but that step #3 can sometime seem like a Far Side (tm) "then a miracle occurs" moment.
Can you file a bug about this? A small webapp with just a WEB-INF/web.xml that proves out this deployment flaw would be good.
Another minor niggle, it is nearly impossible to handle error code 400 in your WEB-INF/web.xml
The problem is that if a bad request comes in, theres no guarantee that the client connecting to you is even HTTP, and since it was a bad request, we have no clue what context's error 400 to dispatch to.