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

Reply via email to