In my application web.xml I define a servlet-mapping for a new extension:
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jss</url-pattern>
</servlet-mapping>
I have not modified, in any way, the global web.xml file.
The application context is loaded just fine, but .jsp files are not handled by the JspServlet (which is declared in global web.xml). The end result being that the JSP source code is served to a web client instead of HTML generated by a compiled jsp class.
.jsp files are compiled if I add the following to my web.xml:
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
However, this seems redundant since that mapping is declared already in the global web.xml file. My expectation was that the global mappings would be merged with the application mappings at deploy time -- which does not seem to be happening in this case.

The current behaviour is by design.
The Servlet specification doesn't cover global defaults but Tomcat's behaviour is line with the rest of the Servlet specification.
For example, if mappings are provided for a Servlet in annotations and in the main web.xml they are not additive. Only the ones from the main web.xml are used. The full precedence order is:
main web.xml > fragments > annotations > defaults

Servlets defined in global web.xml are inherited by webapp web.xml. New servlets defined in web.xml do not eliminate servlets declared in global web.xml, instead they are merged - this spares the app developer from needing to declare the JspServlet, DefaultServlet, etc. in their webapp web.xml files alongside their proprietary servlet declarations.
Mappings defined in global web.xml are also inherited, by default, in the webapp. However, if new mappings are added in web.xml, then global web.xml mappings are dropped. Web developers that want to add new mappings for servlets declared in global web.xml are forced to re-declare the mappings in their webapp web.xml because they are not automatically inherited.
Why would the design of servlet declaration inheritance be out of sync with the design of servlet mapping inheritance? Especially since servlet and servlet mapping declarations have such a close relationship?
This behavior seems inconsistent at best. I'd like to understand the rationale behind this design decision, and how this does not constitute a design bug.

To expand on my previous comment...
When servlet mappings are overridden (e.g. fragment overrides annotations, or application overrides global) all servlet mappings from the overridden source are dropped. The reason for this is simple. If annotations are used to map a servlet to *.foo but the developer wants to change that to *.bar, there is no way to explicitly remove one or more mappings. Therefore, all overridden mappings are removed. The price that is paid for this is that if a developer wants to add a mapping, they have to specify all the overridden mappings as well.
This behaviour has been confirmed as required and correct with the Servlet EG for fragments, annotations and main web.xml. The global defaults just follow this pattern.

This is ASF Bugzilla: the Apache Software Foundation bug system. In case
of problems with the functioning of ASF Bugzilla, please contact
bugzilla-admin@apache.org.
Please Note: this e-mail address is only for reporting problems
with ASF Bugzilla. Mail about any other subject will be silently
ignored.