Author: markt
Date: Tue Mar  3 14:47:12 2015
New Revision: 1663715

URL: http://svn.apache.org/r1663715
Log:
In directly fix https://bz.apache.org/bugzilla/show_bug.cgi?id=57251
Enable Tomcat to detect when a WAR file has been changed while Tomcat is not 
running. Note Tomcat does this by setting the last modified time of the 
expanded directory to the last modified time of the WAR.

Modified:
    tomcat/trunk/java/org/apache/catalina/startup/ExpandWar.java
    tomcat/trunk/java/org/apache/catalina/startup/HostConfig.java
    tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties

Modified: tomcat/trunk/java/org/apache/catalina/startup/ExpandWar.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/ExpandWar.java?rev=1663715&r1=1663714&r2=1663715&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/ExpandWar.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/ExpandWar.java Tue Mar  3 
14:47:12 2015
@@ -55,8 +55,7 @@ public class ExpandWar {
 
     /**
      * Expand the WAR file found at the specified URL into an unpacked
-     * directory structure, and return the absolute pathname to the expanded
-     * directory.
+     * directory structure.
      *
      * @param host Host war is being installed for
      * @param war URL of the web application archive to be expanded
@@ -67,31 +66,62 @@ public class ExpandWar {
      *            WAR file is invalid
      * @exception IOException if an input/output error was encountered
      *  during expansion
+     *
+     * @return The absolute path to the expanded directory foe the given WAR
      */
     public static String expand(Host host, URL war, String pathname)
         throws IOException {
 
-        // Make sure that there is no such directory already existing
-        File docBase = new File(host.getAppBaseFile(), pathname);
-        if (docBase.exists()) {
-            // War file is already installed
-            return (docBase.getAbsolutePath());
-        }
-
-        // Create the new document base directory
-        if(!docBase.mkdir() && !docBase.isDirectory())
-            throw new IOException(sm.getString("expandWar.createFailed", 
docBase));
-
-        // Expand the WAR into the new document base directory
-        String canonicalDocBasePrefix = docBase.getCanonicalPath();
-        if (!canonicalDocBasePrefix.endsWith(File.separator)) {
-            canonicalDocBasePrefix += File.separator;
-        }
+        // Open the connection to the WAR. There is no explicit close method.
+        // You have to get the JarFile and close that.
         JarURLConnection juc = (JarURLConnection) war.openConnection();
         juc.setUseCaches(false);
 
+        // Set up the variables used in the finally block of the following try
         boolean success = false;
+        File docBase = new File(host.getAppBaseFile(), pathname);
+
         try (JarFile jarFile = juc.getJarFile()) {
+
+            // Get the last modified time for the WAR
+            long warLastModified = juc.getContentLengthLong();
+
+            // Check to see of the WAR has been expanded previously
+            if (docBase.exists()) {
+                // A WAR was expanded. Tomcat will have set the last modified
+                // time of the expanded directory to the last modified time of
+                // the WAR so changes to the WAR while Tomcat is stopped can be
+                // detected
+                long dirLastModified = docBase.lastModified();
+
+                if (dirLastModified == warLastModified) {
+                    // No changes to the WAR
+                    return (docBase.getAbsolutePath());
+                }
+
+                log.info(sm.getString("expandWar.deleteOld", docBase));
+
+                // WAR must have been modified. Remove expanded directory.
+                if (!delete(docBase)) {
+                    throw new 
IOException(sm.getString("expandWar.deleteFailed", docBase));
+                }
+            }
+
+            // Create the new document base directory
+            if(!docBase.mkdir() && !docBase.isDirectory()) {
+                throw new IOException(sm.getString("expandWar.createFailed", 
docBase));
+            }
+
+            // Align the last modified time of the directory with the WAR so
+            // changes to the WAR while Tomcat is stopped can be detected
+            docBase.setLastModified(warLastModified);
+
+            // Expand the WAR into the new document base directory
+            String canonicalDocBasePrefix = docBase.getCanonicalPath();
+            if (!canonicalDocBasePrefix.endsWith(File.separator)) {
+                canonicalDocBasePrefix += File.separator;
+            }
+
             Enumeration<JarEntry> jarEntries = jarFile.entries();
             while (jarEntries.hasMoreElements()) {
                 JarEntry jarEntry = jarEntries.nextElement();
@@ -119,7 +149,6 @@ public class ExpandWar {
                     continue;
                 }
 
-
                 try (InputStream input = jarFile.getInputStream(jarEntry)) {
                     if (null == input)
                         throw new 
ZipException(sm.getString("expandWar.missingJarEntry",

Modified: tomcat/trunk/java/org/apache/catalina/startup/HostConfig.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/HostConfig.java?rev=1663715&r1=1663714&r2=1663715&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/HostConfig.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/HostConfig.java Tue Mar  3 
14:47:12 2015
@@ -789,9 +789,17 @@ public class HostConfig
             entry = null;
         }
 
+        // If there is an expanded directory then any xml in that directory
+        // should only be used if the directory is not out of date and
+        // unpackWARs is true. Note the code below may apply further limits
+        boolean useXml = false;
+        if (xml.exists() && unpackWARs && xml.lastModified() == 
war.lastModified()) {
+            useXml = true;
+        }
+
         Context context = null;
         try {
-            if (deployXML && xml.exists() && unpackWARs && !copyXML) {
+            if (deployXML && useXml && !copyXML) {
                 synchronized (digesterLock) {
                     try {
                         context = (Context) digester.parse(xml);

Modified: tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties?rev=1663715&r1=1663714&r2=1663715&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties 
(original)
+++ tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties Tue 
Mar  3 14:47:12 2015
@@ -76,6 +76,7 @@ engineConfig.stop=EngineConfig: Processi
 expandWar.copy=Error copying {0} to {1}
 expandWar.createFailed=Unable to create the directory [{0}]
 expandWar.deleteFailed=[{0}] could not be completely deleted. The presence of 
the remaining files may cause problems
+expandWar.deleteOld=An expanded directory [{0}] was found with a last modified 
time that did not match the associated WAR. It will be deleted.
 expandWar.illegalPath=The archive [{0}] is malformed and will be ignored: an 
entry contains an illegal path [{1}] which was not expanded to [{2}] since that 
is outside of the defined docBase [{3}]
 expandWar.missingJarEntry=Cannot get input stream for JarEntry "{0}" - broken 
WAR file?
 failedContext.start=Failed to process either the global, per-host or 
context-specific context.xml file therefore the [{0}] Context cannot be started.



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to