Author: markt Date: Thu Aug 25 20:59:58 2016 New Revision: 1757754 URL: http://svn.apache.org/viewvc?rev=1757754&view=rev Log: Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=60041 Better error message if a JAR is deleted while a web application is running. Note: Deleting a JAR while the application is running is not supported and errors are expected. Based on a patch by gehui.
Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/LocalStrings.properties tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoaderBase.java tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/LocalStrings.properties?rev=1757754&r1=1757753&r2=1757754&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/LocalStrings.properties (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/LocalStrings.properties Thu Aug 25 20:59:58 2016 @@ -56,6 +56,7 @@ webappClassLoader.checkThreadLocalsForLe webappClassLoader.checkThreadsHttpClient=Found HttpClient keep-alive thread using web application class loader. Fixed by switching thread to the parent class loader. webappClassLoader.getThreadGroupError=Unable to obtain the parent for ThreadGroup [{0}]. It will not be possible to check all threads for potential memory leaks webappClassLoader.loadedByThisOrChildFail=Failed to fully check the entries in an instance of [{0}] for potential memory leaks in context [{1}] +webappClassLoader.jarOpenFail=Failed to open JAR [{0}] webappClassLoader.javaseClassLoaderNull=The j2seClassLoader attribute may not be null webappClassLoader.stopThreadFail=Failed to terminate thread named [{0}] for web application [{1}] webappClassLoader.stopTimerThreadFail=Failed to terminate TimerThread named [{0}] for web application [{1}] Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoaderBase.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoaderBase.java?rev=1757754&r1=1757753&r2=1757754&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoaderBase.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoaderBase.java Thu Aug 25 20:59:58 2016 @@ -156,9 +156,9 @@ public abstract class WebappClassLoaderB private static final String CLASS_FILE_SUFFIX = ".class"; private static final Manifest MANIFEST_UNKNOWN = new Manifest(); - + private static final Method GET_CLASSLOADING_LOCK_METHOD; - + protected static final StringManager sm = StringManager.getManager(Constants.Package); static { @@ -176,7 +176,7 @@ public abstract class WebappClassLoaderB } }); registerParallel.invoke(null); - getClassLoadingLockMethod = + getClassLoadingLockMethod = ClassLoader.class.getDeclaredMethod("getClassLoadingLock", String.class); } } catch (Exception e) { @@ -187,7 +187,7 @@ public abstract class WebappClassLoaderB JVM_THREAD_GROUP_NAMES.add("RMI Runtime"); } - + protected class PrivilegedFindResourceByName implements PrivilegedAction<ResourceEntry> { @@ -963,7 +963,7 @@ public abstract class WebappClassLoaderB } - + protected void copyStateWithoutTransformers(WebappClassLoaderBase base) { base.antiJARLocking = this.antiJARLocking; base.resources = this.resources; @@ -993,7 +993,7 @@ public abstract class WebappClassLoaderB base.searchExternalFirst = this.searchExternalFirst; } - + /** * Add a new repository to the set of places this ClassLoader can look for * classes to be loaded. @@ -1443,7 +1443,7 @@ public abstract class WebappClassLoaderB URL url = null; String path = nameToPath(name); - + if (hasExternalRepositories && searchExternalFirst) url = super.findResource(name); @@ -1770,7 +1770,7 @@ public abstract class WebappClassLoaderB if (log.isDebugEnabled()) log.debug("loadClass(" + name + ", " + resolve + ")"); Class<?> clazz = null; - + // Log access to stopped classloader if (!started) { try { @@ -1779,7 +1779,7 @@ public abstract class WebappClassLoaderB log.info(sm.getString("webappClassLoader.stopped", name), e); } } - + // (0) Check our previously loaded local class cache clazz = findLoadedClass0(name); if (clazz != null) { @@ -1789,7 +1789,7 @@ public abstract class WebappClassLoaderB resolveClass(clazz); return (clazz); } - + // (0.1) Check our previously loaded class cache clazz = findLoadedClass(name); if (clazz != null) { @@ -1799,7 +1799,7 @@ public abstract class WebappClassLoaderB resolveClass(clazz); return (clazz); } - + // (0.2) Try loading the class with the system class loader, to prevent // the webapp from overriding J2SE classes try { @@ -1812,7 +1812,7 @@ public abstract class WebappClassLoaderB } catch (ClassNotFoundException e) { // Ignore } - + // (0.5) Permission to access this class when using a SecurityManager if (securityManager != null) { int i = name.lastIndexOf('.'); @@ -1833,9 +1833,9 @@ public abstract class WebappClassLoaderB } } } - + boolean delegateLoad = delegate || filter(name); - + // (1) Delegate to our parent if requested if (delegateLoad) { if (log.isDebugEnabled()) @@ -1853,7 +1853,7 @@ public abstract class WebappClassLoaderB // Ignore } } - + // (2) Search local repositories if (log.isDebugEnabled()) log.debug(" Searching local repositories"); @@ -1869,7 +1869,7 @@ public abstract class WebappClassLoaderB } catch (ClassNotFoundException e) { // Ignore } - + // (3) Delegate to parent unconditionally if (!delegateLoad) { if (log.isDebugEnabled()) @@ -1888,7 +1888,7 @@ public abstract class WebappClassLoaderB } } } - + throw new ClassNotFoundException(name); } @@ -1903,8 +1903,8 @@ public abstract class WebappClassLoaderB } return this; } - - + + /** * Get the Permissions for a CodeSource. If this instance * of WebappClassLoaderBase is for a web application context, @@ -2102,7 +2102,7 @@ public abstract class WebappClassLoaderB break; } } - + } @@ -3098,9 +3098,8 @@ public abstract class WebappClassLoaderB try { jarFiles[i] = new JarFile(jarRealFiles[i]); } catch (IOException e) { - if (log.isDebugEnabled()) { - log.debug("Failed to open JAR", e); - } + log.warn(sm.getString("webappClassLoader.jarOpenFail", jarFiles[i]), e); + closeJARs(true); return false; } } @@ -3613,8 +3612,8 @@ public abstract class WebappClassLoaderB path.append(name); return path.toString(); } - - + + /** * Returns true if the specified package name is sealed according to the * given manifest. Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1757754&r1=1757753&r2=1757754&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Thu Aug 25 20:59:58 2016 @@ -154,6 +154,12 @@ <fix> Fix a file descriptor leak when reading the global web.xml. (markt) </fix> + <fix> + <bug>60041</bug>: Better error message if a JAR is deleted while a web + application is running. Note: Deleting a JAR while the application is + running is not supported and errors are expected. Based on a patch by + gehui. (markt) + </fix> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org