This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 1347df30e6caf9e67c8108da0eeeee110722f0c0 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 e893c9340b..e0cf8e57ab 100644 --- a/java/org/apache/catalina/startup/LocalStrings.properties +++ b/java/org/apache/catalina/startup/LocalStrings.properties @@ -169,6 +169,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 fadc49f262..af44e397b6 100644 --- a/java/org/apache/catalina/startup/Tomcat.java +++ b/java/org/apache/catalina/startup/Tomcat.java @@ -276,6 +276,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]
