You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2015/03/03 21:34:02 UTC

svn commit: r1663784 - in /tomcat/tc8.0.x/trunk: ./ java/org/apache/catalina/startup/ webapps/docs/config/

Author: markt
Date: Tue Mar  3 20:34:01 2015
New Revision: 1663784

URL: http://svn.apache.org/r1663784
Log:
Indirectly 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 adding a META-INF/war-tracking file to the expanded diretcory and setting the last modified time of this file to the last modified time of the WAR.

Modified:
    tomcat/tc8.0.x/trunk/   (props changed)
    tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/Constants.java
    tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/ExpandWar.java
    tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/HostConfig.java
    tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/LocalStrings.properties
    tomcat/tc8.0.x/trunk/webapps/docs/config/host.xml

Propchange: tomcat/tc8.0.x/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Mar  3 20:34:01 2015
@@ -1 +1 @@
-/tomcat/trunk:1636524,1637156,1637176,1637188,1637331,1637684,1637695,1638720-1638725,1639653,1640010,1640083-1640084,1640088,1640275,1640322,1640347,1640361,1640365,1640403,1640410,1640652,1640655-1640658,1640688,1640700-1640883,1640903,1640976,1640978,1641000,1641026,1641038-1641039,1641051-1641052,1641058,1641064,1641300,1641369,1641374,1641380,1641486,1641634,1641656-1641692,1641704,1641707-1641718,1641720-1641722,1641735,1641981,1642233,1642280,1642554,1642564,1642595,1642606,1642668,1642679,1642697,1642699,1642766,1643002,1643045,1643054-1643055,1643066,1643121,1643128,1643206,1643209-1643210,1643216,1643249,1643270,1643283,1643309-1643310,1643323,1643365-1643366,1643370-1643371,1643465,1643474,1643536,1643570,1643634,1643649,1643651,1643654,1643675,1643731,1643733-1643734,1643761,1643766,1643814,1643937,1643963,1644017,1644169,1644201-1644203,1644321,1644323,1644516,1644523,1644529,1644535,1644730,1644768,1644784-1644785,1644790,1644793,1644815,1644884,1644886,1644890,1644892
 ,1644910,1644924,1644929-1644930,1644935,1644989,1645011,1645247,1645355,1645357-1645358,1645455,1645465,1645469,1645471,1645473,1645475,1645486-1645488,1645626,1645641,1645685,1645743,1645763,1645951-1645953,1645955,1645993,1646098-1646106,1646178,1646220,1646302,1646304,1646420,1646470-1646471,1646476,1646559,1646717-1646723,1646773,1647026,1647042,1647530,1647655,1648304,1648815,1648907,1650081,1650365,1651116,1651120,1651280,1651470,1652938,1652970,1653041,1653471,1653550,1653574,1653797,1653815-1653816,1653819,1653840,1653857,1653888,1653972,1654013,1654030,1654050,1654123,1654148,1654159,1654513,1654515,1654517,1654522,1654524,1654725,1654735,1654766,1654785,1654851-1654852,1654978,1655122-1655124,1655126-1655127,1655129-1655130,1655132-1655133,1655312,1655438,1655441,1655454,1655558,1656087,1656299,1656319,1656331,1656345,1656350,1656590,1656648-1656650,1656657,1657041,1657054,1657374,1657492,1657510,1657565,1657580,1657584,1657586,1657589,1657592,1657607,1657609,1657682,1657
 907,1658207,1658734,1658781,1658790,1658799,1658802,1658804,1658833,1658840,1658966,1659043,1659053,1659059,1659188-1659189,1659216,1659263,1659293,1659304,1659306-1659307,1659382,1659384,1659428,1659471,1659486,1659505,1659516,1659521,1659524,1659559,1659562,1659803,1659806,1659814,1659833,1659862,1659905,1659919,1659948,1659967,1659983-1659984,1660060,1660074,1660077,1660133,1660168,1660331-1660332,1660353,1660358,1660924,1661386,1661867,1661972,1661990,1662200,1662308-1662309,1662548,1662614,1662736,1662985,1662988-1662989,1663264,1663277,1663298,1663324,1663534,1663562,1663676
+/tomcat/trunk:1636524,1637156,1637176,1637188,1637331,1637684,1637695,1638720-1638725,1639653,1640010,1640083-1640084,1640088,1640275,1640322,1640347,1640361,1640365,1640403,1640410,1640652,1640655-1640658,1640688,1640700-1640883,1640903,1640976,1640978,1641000,1641026,1641038-1641039,1641051-1641052,1641058,1641064,1641300,1641369,1641374,1641380,1641486,1641634,1641656-1641692,1641704,1641707-1641718,1641720-1641722,1641735,1641981,1642233,1642280,1642554,1642564,1642595,1642606,1642668,1642679,1642697,1642699,1642766,1643002,1643045,1643054-1643055,1643066,1643121,1643128,1643206,1643209-1643210,1643216,1643249,1643270,1643283,1643309-1643310,1643323,1643365-1643366,1643370-1643371,1643465,1643474,1643536,1643570,1643634,1643649,1643651,1643654,1643675,1643731,1643733-1643734,1643761,1643766,1643814,1643937,1643963,1644017,1644169,1644201-1644203,1644321,1644323,1644516,1644523,1644529,1644535,1644730,1644768,1644784-1644785,1644790,1644793,1644815,1644884,1644886,1644890,1644892
 ,1644910,1644924,1644929-1644930,1644935,1644989,1645011,1645247,1645355,1645357-1645358,1645455,1645465,1645469,1645471,1645473,1645475,1645486-1645488,1645626,1645641,1645685,1645743,1645763,1645951-1645953,1645955,1645993,1646098-1646106,1646178,1646220,1646302,1646304,1646420,1646470-1646471,1646476,1646559,1646717-1646723,1646773,1647026,1647042,1647530,1647655,1648304,1648815,1648907,1650081,1650365,1651116,1651120,1651280,1651470,1652938,1652970,1653041,1653471,1653550,1653574,1653797,1653815-1653816,1653819,1653840,1653857,1653888,1653972,1654013,1654030,1654050,1654123,1654148,1654159,1654513,1654515,1654517,1654522,1654524,1654725,1654735,1654766,1654785,1654851-1654852,1654978,1655122-1655124,1655126-1655127,1655129-1655130,1655132-1655133,1655312,1655438,1655441,1655454,1655558,1656087,1656299,1656319,1656331,1656345,1656350,1656590,1656648-1656650,1656657,1657041,1657054,1657374,1657492,1657510,1657565,1657580,1657584,1657586,1657589,1657592,1657607,1657609,1657682,1657
 907,1658207,1658734,1658781,1658790,1658799,1658802,1658804,1658833,1658840,1658966,1659043,1659053,1659059,1659188-1659189,1659216,1659263,1659293,1659304,1659306-1659307,1659382,1659384,1659428,1659471,1659486,1659505,1659516,1659521,1659524,1659559,1659562,1659803,1659806,1659814,1659833,1659862,1659905,1659919,1659948,1659967,1659983-1659984,1660060,1660074,1660077,1660133,1660168,1660331-1660332,1660353,1660358,1660924,1661386,1661867,1661972,1661990,1662200,1662308-1662309,1662548,1662614,1662736,1662985,1662988-1662989,1663264,1663277,1663298,1663324,1663534,1663562,1663676,1663715,1663754,1663768,1663772,1663781

Modified: tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/Constants.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/Constants.java?rev=1663784&r1=1663783&r2=1663784&view=diff
==============================================================================
--- tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/Constants.java (original)
+++ tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/Constants.java Tue Mar  3 20:34:01 2015
@@ -31,6 +31,7 @@ public final class Constants {
     public static final String DefaultWebXml = "conf/web.xml";
     public static final String HostContextXml = "context.xml.default";
     public static final String HostWebXml = "web.xml.default";
+    public static final String WarTracker = "/META-INF/war-tracker";
 
     /**
      * A dummy value used to suppress loading the default web.xml file.

Modified: tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/ExpandWar.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/ExpandWar.java?rev=1663784&r1=1663783&r2=1663784&view=diff
==============================================================================
--- tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/ExpandWar.java (original)
+++ tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/ExpandWar.java Tue Mar  3 20:34:01 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,57 @@ 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);
+        File warTracker = new File(host.getAppBaseFile(), pathname + Constants.WarTracker);
+
         try (JarFile jarFile = juc.getJarFile()) {
+
+            // Get the last modified time for the WAR
+            long warLastModified = juc.getLastModified();
+
+            // 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
+                if (!warTracker.exists() || warTracker.lastModified() == warLastModified) {
+                    // No (detectable) changes to the WAR
+                    success = true;
+                    return (docBase.getAbsolutePath());
+                }
+
+                // WAR must have been modified. Remove expanded directory.
+                log.info(sm.getString("expandWar.deleteOld", docBase));
+                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));
+            }
+
+            // 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 +144,6 @@ public class ExpandWar {
                     continue;
                 }
 
-
                 try (InputStream input = jarFile.getInputStream(jarEntry)) {
                     if (null == input)
                         throw new ZipException(sm.getString("expandWar.missingJarEntry",
@@ -132,6 +156,11 @@ public class ExpandWar {
                         expandedFile.setLastModified(lastModified);
                     }
                 }
+
+                // Create the warTracker file and align the last modified time
+                // with the last modified time of the WAR
+                warTracker.createNewFile();
+                warTracker.setLastModified(warLastModified);
             }
             success = true;
         } catch (IOException e) {

Modified: tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/HostConfig.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/HostConfig.java?rev=1663784&r1=1663783&r2=1663784&view=diff
==============================================================================
--- tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/HostConfig.java (original)
+++ tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/HostConfig.java Tue Mar  3 20:34:01 2015
@@ -774,7 +774,10 @@ public class HostConfig
     protected void deployWAR(ContextName cn, File war) {
 
         File xml = new File(host.getAppBaseFile(),
-                cn.getBaseName() + "/META-INF/context.xml");
+                cn.getBaseName() + "/" + Constants.ApplicationContextXml);
+
+        File warTracker = new File(host.getAppBaseFile(),
+                cn.getBaseName() + "/" + Constants.WarTracker);
 
         boolean xmlInWar = false;
         JarEntry entry = null;
@@ -789,9 +792,20 @@ 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 the xml file exists then expandedDir must exists so no need to
+        // test that here
+        if (xml.exists() && unpackWARs &&
+                (!warTracker.exists() || warTracker.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/tc8.0.x/trunk/java/org/apache/catalina/startup/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/LocalStrings.properties?rev=1663784&r1=1663783&r2=1663784&view=diff
==============================================================================
--- tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/LocalStrings.properties (original)
+++ tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/LocalStrings.properties Tue Mar  3 20:34:01 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.

Modified: tomcat/tc8.0.x/trunk/webapps/docs/config/host.xml
URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/webapps/docs/config/host.xml?rev=1663784&r1=1663783&r2=1663784&view=diff
==============================================================================
--- tomcat/tc8.0.x/trunk/webapps/docs/config/host.xml (original)
+++ tomcat/tc8.0.x/trunk/webapps/docs/config/host.xml Tue Mar  3 20:34:01 2015
@@ -275,10 +275,15 @@
         placed in the <code>appBase</code> directory as web application
         archive (WAR) files to be unpacked into a corresponding disk directory
         structure, <code>false</code> to run such web applications directly
-        from a WAR file. WAR files located outside of the Host's
-        <strong>appBase</strong> will not be expanded. See
+        from a WAR file. See
         <a href="#Automatic_Application_Deployment">Automatic Application
         Deployment</a> for more information.</p>
+        <p>Note: If Tomcat expands the WAR file then it will add a file
+        (<code>/META-INF/war-tracking</code>) to the unpacked directory
+        structure which it uses to detect changes in the WAR file while Tomcat
+        is not running. Any such change will trigger the deletion of the
+        expanded directory and the deployment of the updated WAR file when
+        Tomcat next starts.</p>
       </attribute>
 
       <attribute name="workDir" required="false">



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


Re: svn commit: r1663784 - in /tomcat/tc8.0.x/trunk: ./ java/org/apache/catalina/startup/ webapps/docs/config/

Posted by Mark Thomas <ma...@apache.org>.
On 20/03/2015 13:51, Konstantin Kolinko wrote:
> 1) I see no changelog entry for this new feature.
> 
> Bugzilla reference:
> https://bz.apache.org/bugzilla/show_bug.cgi?id=57251#c31

Added.

> 2) A user is asking that this feature is mentioned in Tomcat 7 docs,
> as if it is already working
> http://tomcat.apache.org/tomcat-7.0-doc/deployer-howto.html#post_3798
> 
> [quote]
> From the "Deployment on Tomcat startup" section: "2. Exploded web
> applications not referenced by any Context Descriptor will then be
> deployed. >>If they have an associated .WAR file in the appBase and it
> is newer than the exploded web application, the exploded directory
> will be removed and the webapp will be redeployed from the .WAR<< "
> [/quote]
> 
> Tomcat 6 docs also has that phrase.
> 
> For Tomcat 6 the way to go is to fix the docs.
> For Tomcat 7 there is a chance to backport this feature.

For now, I've fixed the docs for both. I don't plan to back-port this
feature.

Mark


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


Re: svn commit: r1663784 - in /tomcat/tc8.0.x/trunk: ./ java/org/apache/catalina/startup/ webapps/docs/config/

Posted by Konstantin Kolinko <kn...@gmail.com>.
1) I see no changelog entry for this new feature.

Bugzilla reference:
https://bz.apache.org/bugzilla/show_bug.cgi?id=57251#c31


2) A user is asking that this feature is mentioned in Tomcat 7 docs,
as if it is already working
http://tomcat.apache.org/tomcat-7.0-doc/deployer-howto.html#post_3798

[quote]
>From the "Deployment on Tomcat startup" section: "2. Exploded web
applications not referenced by any Context Descriptor will then be
deployed. >>If they have an associated .WAR file in the appBase and it
is newer than the exploded web application, the exploded directory
will be removed and the webapp will be redeployed from the .WAR<< "
[/quote]

Tomcat 6 docs also has that phrase.

For Tomcat 6 the way to go is to fix the docs.
For Tomcat 7 there is a chance to backport this feature.



2015-03-03 23:34 GMT+03:00  <ma...@apache.org>:
> Author: markt
> Date: Tue Mar  3 20:34:01 2015
> New Revision: 1663784
>
> URL: http://svn.apache.org/r1663784
> Log:
> Indirectly 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 adding a META-INF/war-tracking file to the expanded diretcory and setting the last modified time of this file to the last modified time of the WAR.
>
> Modified:
>     tomcat/tc8.0.x/trunk/   (props changed)
>     tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/Constants.java
>     tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/ExpandWar.java
>     tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/HostConfig.java
>     tomcat/tc8.0.x/trunk/java/org/apache/catalina/startup/LocalStrings.properties
>     tomcat/tc8.0.x/trunk/webapps/docs/config/host.xml
>

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