This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit d63a8e1b05ab2ba3c4182abcd08c3039a6bc0298 Author: opencode <[email protected]> AuthorDate: Thu Oct 8 16:57:59 2026 +0200 Remove the incomplete WAR left behind when copying a WAR to the appBase fails. addWebapp(String, URL) creates the target WAR in the host's appBase before streaming the source into it. If the copy failed part way through, the truncated WAR remained in the appBase and the method's own conflict check then rejected every subsequent attempt to deploy to the same context path with an IllegalArgumentException, so a transient I/O error turned into a permanent failure until the file was deleted manually. Delete the incomplete WAR when the copy throws an IOException before rethrowing the original exception. If the file cannot be deleted, log a warning naming its location so the administrator knows what to remove. --- java/org/apache/catalina/startup/LocalStrings.properties | 1 + java/org/apache/catalina/startup/Tomcat.java | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/java/org/apache/catalina/startup/LocalStrings.properties b/java/org/apache/catalina/startup/LocalStrings.properties index 1833c0f36e..414ad0f37d 100644 --- a/java/org/apache/catalina/startup/LocalStrings.properties +++ b/java/org/apache/catalina/startup/LocalStrings.properties @@ -168,6 +168,7 @@ setNextNamingRule.invalidParent=Parent should be either a Context or a NamingRes tomcat.addWebapp.conflictChild=Unable to deploy WAR at [{0}] to context path [{1}] because of existing context [{2}] tomcat.addWebapp.conflictFile=Unable to deploy WAR at [{0}] to context path [{1}] because of existing file [{2}] +tomcat.addWebapp.copyCleanupFailed=Unable to deploy WAR at [{0}] to context path [{1}]. The incomplete copy at [{2}] could not be deleted. Remove that file manually before attempting to deploy to this context path again. tomcat.baseDirMakeFail=Unable to create the directory [{0}] to use as the base directory tomcat.baseDirNotDir=The location [{0}] specified for the base directory is not a directory tomcat.defaultMimeTypeMappingsFail=Unable to load the default MIME types diff --git a/java/org/apache/catalina/startup/Tomcat.java b/java/org/apache/catalina/startup/Tomcat.java index 570355af85..8e2674a01e 100644 --- a/java/org/apache/catalina/startup/Tomcat.java +++ b/java/org/apache/catalina/startup/Tomcat.java @@ -278,6 +278,16 @@ public class Tomcat { try (InputStream is = uConn.getInputStream(); OutputStream os = new FileOutputStream(targetWar)) { IOTools.flow(is, os); + } catch (IOException e) { + // An incomplete WAR left in the appBase would block any subsequent attempt to deploy + // to this context path via the conflict checks above, so remove it before rethrowing. + if (targetWar.exists() && !targetWar.delete()) { + Logger.getLogger(getLoggerName(getHost(), contextPath)).log(Level.WARNING, + sm.getString("tomcat.addWebapp.copyCleanupFailed", source, contextPath, + targetWar.getAbsolutePath()), + e); + } + throw e; } return addWebapp(contextPath, targetWar.getAbsolutePath()); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
