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 2013/11/05 01:04:59 UTC

svn commit: r1538832 - in /tomcat/trunk/java/org/apache/catalina/loader: LocalStrings.properties WebappClassLoader.java

Author: markt
Date: Tue Nov  5 00:04:59 2013
New Revision: 1538832

URL: http://svn.apache.org/r1538832
Log:
Simplify modification tracking

Modified:
    tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties
    tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java

Modified: tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties?rev=1538832&r1=1538831&r2=1538832&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties Tue Nov  5 00:04:59 2013
@@ -35,6 +35,7 @@ webappClassLoader.loadedByThisOrChildFai
 webappClassLoader.jarsAdded=One of more JARs have been added to the web application [{0}]
 webappClassLoader.jarsModified=One of more JARs have been modified in the web application [{0}]
 webappClassLoader.jarsRemoved=One of more JARs have been removed from the web application [{0}]
+webappClassLoader.resourceModified=Resource [{0}] has been modified. The last modified time was [{1}] and is now [{2}]
 webappClassLoader.stopThreadFail=Failed to terminate thread named [{0}] for web application [{1}]
 webappClassLoader.stopTimerThreadFail=Failed to terminate TimerThread named [{0}] for web application [{1}]
 webappClassLoader.validationErrorJarPath=Unable to validate JAR entry with name {0}

Modified: tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java?rev=1538832&r1=1538831&r2=1538832&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java (original)
+++ tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java Tue Nov  5 00:04:59 2013
@@ -44,6 +44,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.ConcurrentModificationException;
+import java.util.Date;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -51,8 +52,10 @@ import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.ResourceBundle;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.jar.Attributes;
@@ -272,7 +275,8 @@ public class WebappClassLoader extends U
      * The cache of ResourceEntry for classes and resources we have loaded,
      * keyed by resource name.
      */
-    protected final HashMap<String, ResourceEntry> resourceEntries = new HashMap<>();
+    protected final Map<String, ResourceEntry> resourceEntries =
+            new ConcurrentHashMap<>();
 
 
     /**
@@ -291,20 +295,6 @@ public class WebappClassLoader extends U
 
 
     /**
-     * The list of JARs last modified dates, in the order they should be
-     * searched for locally loaded classes or resources.
-     */
-    protected long[] lastModifiedDates = new long[0];
-
-
-    /**
-     * The list of resources which should be checked when checking for
-     * modifications.
-     */
-    protected String[] paths = new String[0];
-
-
-    /**
      * A list of read File and Jndi Permission's required if this loader
      * is for a web application context.
      */
@@ -708,8 +698,6 @@ public class WebappClassLoader extends U
         loader.clearReferencesLogFactoryRelease = this.clearReferencesLogFactoryRelease;
         loader.clearReferencesHttpClientKeepAliveThread = this.clearReferencesHttpClientKeepAliveThread;
 
-        loader.paths = this.paths.clone();
-
         loader.permissionList.addAll(this.permissionList);
         loader.loaderPC.putAll(this.loaderPC);
 
@@ -726,30 +714,20 @@ public class WebappClassLoader extends U
         if (log.isDebugEnabled())
             log.debug("modified()");
 
-        // Checking for modified loaded resources
-        int length = paths.length;
-
-        // A rare race condition can occur in the updates of the two arrays
-        // It's totally ok if the latest class added is not checked (it will
-        // be checked the next time
-        int length2 = lastModifiedDates.length;
-        if (length > length2)
-            length = length2;
-
-        for (int i = 0; i < length; i++) {
-            long lastModified =
-                    resources.getResource(paths[i]).getLastModified();
-            if (lastModified != lastModifiedDates[i]) {
+        for (Entry<String,ResourceEntry> entry : resourceEntries.entrySet()) {
+            long cachedLastModified = entry.getValue().lastModified;
+            long lastModified = resources.getClassLoaderResource(
+                    entry.getKey()).getLastModified();
+            if (lastModified != cachedLastModified) {
                 if( log.isDebugEnabled() )
-                    log.debug("  Resource '" + paths[i]
-                              + "' was modified; Date is now: "
-                              + new java.util.Date(lastModified) + " Was: "
-                              + new java.util.Date(lastModifiedDates[i]));
+                    log.debug(sm.getString("webappClassLoader.resourceModified",
+                            entry.getKey(),
+                            new Date(cachedLastModified),
+                            new Date(lastModified)));
                 return true;
             }
         }
 
-
         // Check if JARs have been added or removed
         WebResource[] jars = resources.listResources("/WEB-INF/lib");
         if (jars.length > jarModificationTimes.size()) {
@@ -1462,8 +1440,6 @@ public class WebappClassLoader extends U
         resourceEntries.clear();
         jarModificationTimes.clear();
         resources = null;
-        lastModifiedDates = null;
-        paths = null;
         parent = null;
 
         permissionList.clear();
@@ -1595,9 +1571,7 @@ public class WebappClassLoader extends U
 
     private final void clearReferencesStaticFinal() {
 
-        @SuppressWarnings("unchecked")
-        Collection<ResourceEntry> values =
-            ((HashMap<String,ResourceEntry>) resourceEntries.clone()).values();
+        Collection<ResourceEntry> values = resourceEntries.values();
         Iterator<ResourceEntry> loadedClasses = values.iterator();
         //
         // walk through all loaded class to trigger initialization for
@@ -2432,7 +2406,6 @@ public class WebappClassLoader extends U
         }
 
         return clazz;
-
     }
 
 
@@ -2463,7 +2436,6 @@ public class WebappClassLoader extends U
 
         boolean fileNeedConvert = false;
 
-        String fullPath = "/WEB-INF/classes/" + path;
         resource = resources.getClassLoaderResource("/" + path);
 
         if (!resource.exists()) {
@@ -2484,27 +2456,6 @@ public class WebappClassLoader extends U
             }
         }
 
-        // Register the full path for modification checking
-        // Note: Only syncing on a 'constant' object is needed
-        synchronized (allPermission) {
-
-            int j;
-
-            long[] result2 = new long[lastModifiedDates.length + 1];
-            for (j = 0; j < lastModifiedDates.length; j++) {
-                result2[j] = lastModifiedDates[j];
-            }
-            result2[lastModifiedDates.length] = entry.lastModified;
-            lastModifiedDates = result2;
-
-            String[] result = new String[paths.length + 1];
-            for (j = 0; j < paths.length; j++) {
-                result[j] = paths[j];
-            }
-            result[paths.length] = fullPath;
-            paths = result;
-        }
-
         JarEntry jarEntry = null;
 
         try {



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