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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org