Created attachment 33415 [details] catalina.2016-01-07.log Noted when running a week old build of Tomcat 6 that used a different default value for mapperContextRootRedirectEnabled. Steps to reproduce with current Tomcat 6 trunk: 1. Edit default conf/context.xml as <Context mapperContextRootRedirectEnabled="false"> 2. Run catalina.bat start catalina.bat stop 3. Tomcat shuts down successfully (immediately), but catalina.2016-01-07.log contains 2 copies of the following message: 07.01.2016 4:50:30 org.apache.catalina.connector.MapperListener handleNotification WARNING: Error unregistering webapp Catalina:j2eeType=WebModule,name=//localhost/,J2EEApplication=none,J2EEServer=none java.lang.ArrayIndexOutOfBoundsException: -1 at org.apache.tomcat.util.http.mapper.Mapper.internalMapWrapper(Mapper.java:769) at org.apache.tomcat.util.http.mapper.Mapper.internalMap(Mapper.java:691) at org.apache.tomcat.util.http.mapper.Mapper.map(Mapper.java:577) at org.apache.catalina.connector.MapperListener.unregisterContext(MapperListener.java:481) See attached log file for details.
Only Tomcat 6 is affected. I tested current 7/8/9 trunks and they shut down cleanly in this configuration.
Observations -------------- 1. Comparing Mapper.internalMapWrapper() implementations between Tomcat 6 and Tomcat 7, they are not very different. The only substantial difference is a missing block of code in Tomcat 6 (-- the code block just above "Rule 7". In Tomcat 7 it is commented as "/* welcome file processing - take 2"), but it does not matter for this bug. It fails earlier. 2. MapperListener implementations are quite different. In Tomcat 7 it is a LifecycleListener, and has a reference to Context that is the cause of the event. In Tomcat 6 it is a NotificationListener and this feature is triggered by unregistration of a JMX MBean. - See stacktrace attached in Description (Comment 0) of this bug. As NotificationListener in Tomcat 6 does not have a reference to Context, it uses Mapper to get one, simulating a request with (host name = hostName, uri = contextName). For ROOT context the uri becomes "", and the failure happens. 3. A similar call to Mapper.map() is used in Tomcat 7 and later to implement ApplicationContext.getContext(uri). There is a check in that method that uri.startsWith("/"), so it does not use an empty URI. Conclusion ----------- - NotificationListener of Tomcat 6 is the only place in Tomcat 6/7/8/9 that calls Mapper.map() with an empty string as URI. While it is possible to improve Mapper, I think it is sufficient to add workaround to NotificationListener to use a valid URI ("/") in this case.
Fixed in Tomcat 6 by r1727846 and will be in 6.0.45 onwards.