Dear Mark Thomas, other developers and list members, caused by the requirement of an external software product, I currently have to upgrade a Tomcat-8.5 installation from Tomcat-8.5.23 to >=8.5.32 and therefore I concretely choose 8.5.38. As I expect from a minor update, in the first moment this is a smooth thing. But surprisingly I run in a very strange issue: There is -- at least for me -- a remarkable change in the behavior of the handling of WAR deployments: If the deployment unit is a symbolic link, the new version will not use anymore the "extension" of the name of the symbolic link to determine the "kind of application" but will "resolve" the link(s) and use the tail of the name of the final destination instead:
* If I a deployment is a file named 'foo.war', all works well as before and expected. * If it an symbolic link named 'foo.war' pointing to '[<anypath>/]bar.war', also all works as before and expected (i.e. the root context name is 'foo') * But now and in contrast to before: if the link destination don't have the extension '.war', the deployment process will fail. From this, after establishing the link foo.war -> /some/fill/path/to/destination/bar.an_extension for deployment, with the newer Tomcat version I get the error 20190308-092433.557 ERROR [catalina-exec-38] [] [[/manager]] FAIL - Application at context path [/foo] could not be started org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/foo]] at org.apache.catalina.util.LifecycleBase.start(Unknown Source) at org.apache.catalina.manager.ManagerServlet.start(Unknown Source) at org.apache.catalina.manager.HTMLManagerServlet.start(Unknown Source) at org.apache.catalina.manager.HTMLManagerServlet.doPost(Unknown Source) at javax.servlet.http.HttpServlet.service(Unknown Source) at javax.servlet.http.HttpServlet.service(Unknown Source) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Unknown Source) at org.apache.catalina.core.ApplicationFilterChain.doFilter(Unknown Source) at org.apache.catalina.filters.CsrfPreventionFilter.doFilter(Unknown Source) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Unknown Source) at org.apache.catalina.core.ApplicationFilterChain.doFilter(Unknown Source) at org.apache.tomcat.websocket.server.WsFilter.doFilter(Unknown Source) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Unknown Source) at org.apache.catalina.core.ApplicationFilterChain.doFilter(Unknown Source) at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(Unknown Source) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Unknown Source) at org.apache.catalina.core.ApplicationFilterChain.doFilter(Unknown Source) at org.apache.catalina.core.StandardWrapperValve.invoke(Unknown Source) at org.apache.catalina.core.StandardContextValve.invoke(Unknown Source) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(Unknown Source) at org.apache.catalina.core.StandardHostValve.invoke(Unknown Source) at org.apache.catalina.valves.ErrorReportValve.invoke(Unknown Source) at org.apache.catalina.valves.RequestFilterValve.process(Unknown Source) at org.apache.catalina.valves.RemoteAddrValve.invoke(Unknown Source) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(Unknown Source) at org.apache.catalina.core.StandardEngineValve.invoke(Unknown Source) at org.apache.catalina.connector.CoyoteAdapter.service(Unknown Source) at org.apache.coyote.http11.Http11Processor.service(Unknown Source) at org.apache.coyote.AbstractProcessorLight.process(Unknown Source) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(Unknown Source) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(Unknown Source) at org.apache.tomcat.util.net.SocketProcessorBase.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) Caused by: org.apache.catalina.LifecycleException: Failed to start component [org.apache.catalina.webresources.StandardRoot@23279aae] at org.apache.catalina.util.LifecycleBase.start(Unknown Source) at org.apache.catalina.core.StandardContext.resourcesStart(Unknown Source) at org.apache.catalina.core.StandardContext.startInternal(Unknown Source) ... 36 more Caused by: java.lang.IllegalArgumentException: The main resource set specified [/some/fill/path/to/destination/bar.an_extension] is not valid at org.apache.catalina.webresources.StandardRoot.createMainResourceSet(Unknown Source) at org.apache.catalina.webresources.StandardRoot.startInternal(Unknown Source) ... 39 more At this state, the Context is listed as '/foo' in the Tomcat Manager (with running=false) and if I start it here, the Message is equivalent: FAIL - Application at context path [/foo] could not be started FAIL - Encountered exception [org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/foo]]] Background: For more than ten years I'm using this mechanism of linking for deployments. I have a shared filesystem resource with a "repository" holding all our application deployment artefacts, structured by projects and named by internal names and versions. There's a Tomcat farm with a couple of Tomcats in different stages. For deployment of a concrete version, this is just linked on the webapp directory of a concrete virtual host on a concrete tomcat (in fact: mostly two for failover redundancy) on a concrete stage and the link name is used to define the context path (i.e. the visible URL) of the application. With the new Tomcat version, this breaks because the names in the "repository" don't end with '.war' and I don't want to change the whole internal deployment process including agreements and script framework. Instead, please point me to the change in the source code that have changed since 8.5.23 and is the root cause for this new behavior. Because I'm using Gentoo and will build the Tomcat from the source, it's no big deal for me to patch the sources. But I'm not familiar with the source code at all. Thank you for support in advance Guido