This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push: new 9213e5a57e Code clean-up - no functional change 9213e5a57e is described below commit 9213e5a57ed1490216082d342000fe98c2be41f2 Author: Mark Thomas <ma...@apache.org> AuthorDate: Wed Sep 6 11:05:47 2023 +0100 Code clean-up - no functional change --- .../apache/catalina/loader/JdbcLeakPrevention.java | 29 +- .../catalina/loader/ParallelWebappClassLoader.java | 17 +- java/org/apache/catalina/loader/ResourceEntry.java | 4 +- .../apache/catalina/loader/WebappClassLoader.java | 20 +- .../catalina/loader/WebappClassLoaderBase.java | 703 ++++++++------------- java/org/apache/catalina/loader/WebappLoader.java | 132 ++-- 6 files changed, 359 insertions(+), 546 deletions(-) diff --git a/java/org/apache/catalina/loader/JdbcLeakPrevention.java b/java/org/apache/catalina/loader/JdbcLeakPrevention.java index adbf8f2b03..cdd5b8b974 100644 --- a/java/org/apache/catalina/loader/JdbcLeakPrevention.java +++ b/java/org/apache/catalina/loader/JdbcLeakPrevention.java @@ -26,16 +26,11 @@ import java.util.List; import java.util.Set; /** - * This class is loaded by {@link WebappClassLoaderBase} to enable it to - * deregister JDBC drivers forgotten by the web application. There are some - * classloading hacks involved - see - * {@link WebappClassLoaderBase#clearReferences()} for details - but the short - * version is do not just create a new instance of this class with the new - * keyword. - * - * Since this class is loaded by {@link WebappClassLoaderBase}, it cannot refer - * to any internal Tomcat classes as that will cause the security manager to - * complain. + * This class is loaded by {@link WebappClassLoaderBase} to enable it to deregister JDBC drivers forgotten by the web + * application. There are some classloading hacks involved - see {@link WebappClassLoaderBase#clearReferences()} for + * details - but the short version is do not just create a new instance of this class with the new keyword. Since this + * class is loaded by {@link WebappClassLoaderBase}, it cannot refer to any internal Tomcat classes as that will cause + * the security manager to complain. */ public class JdbcLeakPrevention { @@ -43,13 +38,10 @@ public class JdbcLeakPrevention { List<String> driverNames = new ArrayList<>(); /* - * DriverManager.getDrivers() has a nasty side-effect of registering - * drivers that are visible to this class loader but haven't yet been - * loaded. Therefore, the first call to this method a) gets the list - * of originally loaded drivers and b) triggers the unwanted - * side-effect. The second call gets the complete list of drivers - * ensuring that both original drivers and any loaded as a result of the - * side-effects are all de-registered. + * DriverManager.getDrivers() has a nasty side-effect of registering drivers that are visible to this class + * loader but haven't yet been loaded. Therefore, the first call to this method a) gets the list of originally + * loaded drivers and b) triggers the unwanted side-effect. The second call gets the complete list of drivers + * ensuring that both original drivers and any loaded as a result of the side-effects are all de-registered. */ Set<Driver> originalDrivers = new HashSet<>(); Enumeration<Driver> drivers = DriverManager.getDrivers(); @@ -60,8 +52,7 @@ public class JdbcLeakPrevention { while (drivers.hasMoreElements()) { Driver driver = drivers.nextElement(); // Only unload the drivers this web app loaded - if (driver.getClass().getClassLoader() != - this.getClass().getClassLoader()) { + if (driver.getClass().getClassLoader() != this.getClass().getClassLoader()) { continue; } // Only report drivers that were originally registered. Skip any diff --git a/java/org/apache/catalina/loader/ParallelWebappClassLoader.java b/java/org/apache/catalina/loader/ParallelWebappClassLoader.java index 9f6b469780..167f72de3e 100644 --- a/java/org/apache/catalina/loader/ParallelWebappClassLoader.java +++ b/java/org/apache/catalina/loader/ParallelWebappClassLoader.java @@ -44,17 +44,14 @@ public class ParallelWebappClassLoader extends WebappClassLoaderBase { /** - * Returns a copy of this class loader without any class file - * transformers. This is a tool often used by Java Persistence API - * providers to inspect entity classes in the absence of any - * instrumentation, something that can't be guaranteed within the - * context of a {@link java.lang.instrument.ClassFileTransformer}'s - * {@link java.lang.instrument.ClassFileTransformer#transform(ClassLoader, - * String, Class, java.security.ProtectionDomain, byte[]) transform} method. + * Returns a copy of this class loader without any class file transformers. This is a tool often used by Java + * Persistence API providers to inspect entity classes in the absence of any instrumentation, something that can't + * be guaranteed within the context of a {@link java.lang.instrument.ClassFileTransformer}'s + * {@link java.lang.instrument.ClassFileTransformer#transform(ClassLoader, String, Class, java.security.ProtectionDomain, byte[]) + * transform} method. * <p> - * The returned class loader's resource cache will have been cleared - * so that classes already instrumented will not be retained or - * returned. + * The returned class loader's resource cache will have been cleared so that classes already instrumented will not + * be retained or returned. * * @return the transformer-free copy of this class loader. */ diff --git a/java/org/apache/catalina/loader/ResourceEntry.java b/java/org/apache/catalina/loader/ResourceEntry.java index 4b7092686e..b9eeff7e7d 100644 --- a/java/org/apache/catalina/loader/ResourceEntry.java +++ b/java/org/apache/catalina/loader/ResourceEntry.java @@ -24,8 +24,8 @@ package org.apache.catalina.loader; public class ResourceEntry { /** - * The "last modified" time of the origin file at the time this resource - * was loaded, in milliseconds since the epoch. + * The "last modified" time of the origin file at the time this resource was loaded, in milliseconds since the + * epoch. */ public long lastModified = -1; diff --git a/java/org/apache/catalina/loader/WebappClassLoader.java b/java/org/apache/catalina/loader/WebappClassLoader.java index 106be04acb..58a84a2bcc 100644 --- a/java/org/apache/catalina/loader/WebappClassLoader.java +++ b/java/org/apache/catalina/loader/WebappClassLoader.java @@ -31,17 +31,14 @@ public class WebappClassLoader extends WebappClassLoaderBase { /** - * Returns a copy of this class loader without any class file - * transformers. This is a tool often used by Java Persistence API - * providers to inspect entity classes in the absence of any - * instrumentation, something that can't be guaranteed within the - * context of a {@link java.lang.instrument.ClassFileTransformer}'s - * {@link java.lang.instrument.ClassFileTransformer#transform(ClassLoader, - * String, Class, java.security.ProtectionDomain, byte[]) transform} method. + * Returns a copy of this class loader without any class file transformers. This is a tool often used by Java + * Persistence API providers to inspect entity classes in the absence of any instrumentation, something that can't + * be guaranteed within the context of a {@link java.lang.instrument.ClassFileTransformer}'s + * {@link java.lang.instrument.ClassFileTransformer#transform(ClassLoader, String, Class, java.security.ProtectionDomain, byte[]) + * transform} method. * <p> - * The returned class loader's resource cache will have been cleared - * so that classes already instrumented will not be retained or - * returned. + * The returned class loader's resource cache will have been cleared so that classes already instrumented will not + * be retained or returned. * * @return the transformer-free copy of this class loader. */ @@ -63,8 +60,7 @@ public class WebappClassLoader extends WebappClassLoaderBase { /** - * This class loader is not parallel capable so lock on the class loader - * rather than a per-class lock. + * This class loader is not parallel capable so lock on the class loader rather than a per-class lock. */ @Override protected Object getClassLoadingLock(String className) { diff --git a/java/org/apache/catalina/loader/WebappClassLoaderBase.java b/java/org/apache/catalina/loader/WebappClassLoaderBase.java index 3d816a3c51..1ed019a06f 100644 --- a/java/org/apache/catalina/loader/WebappClassLoaderBase.java +++ b/java/org/apache/catalina/loader/WebappClassLoaderBase.java @@ -81,42 +81,33 @@ import org.apache.tomcat.util.threads.ThreadPoolExecutor; /** * Specialized web application class loader. * <p> - * This class loader is a full reimplementation of the - * <code>URLClassLoader</code> from the JDK. It is designed to be fully - * compatible with a normal <code>URLClassLoader</code>, although its internal - * behavior may be completely different. + * This class loader is a full reimplementation of the <code>URLClassLoader</code> from the JDK. It is designed to be + * fully compatible with a normal <code>URLClassLoader</code>, although its internal behavior may be completely + * different. * <p> - * <strong>IMPLEMENTATION NOTE</strong> - By default, this class loader follows - * the delegation model required by the specification. The bootstrap class - * loader will be queried first, then the local repositories, and only then - * delegation to the parent class loader will occur. This allows the web - * application to override any shared class except the classes from J2SE. - * Special handling is provided from the JAXP XML parser interfaces, the JNDI - * interfaces, and the classes from the servlet API, which are never loaded - * from the webapp repositories. The <code>delegate</code> property - * allows an application to modify this behavior to move the parent class loader - * ahead of the local repositories. + * <strong>IMPLEMENTATION NOTE</strong> - By default, this class loader follows the delegation model required by the + * specification. The bootstrap class loader will be queried first, then the local repositories, and only then + * delegation to the parent class loader will occur. This allows the web application to override any shared class except + * the classes from J2SE. Special handling is provided from the JAXP XML parser interfaces, the JNDI interfaces, and the + * classes from the servlet API, which are never loaded from the webapp repositories. The <code>delegate</code> property + * allows an application to modify this behavior to move the parent class loader ahead of the local repositories. * <p> - * <strong>IMPLEMENTATION NOTE</strong> - Due to limitations in Jasper - * compilation technology, any repository which contains classes from - * the servlet API will be ignored by the class loader. + * <strong>IMPLEMENTATION NOTE</strong> - Due to limitations in Jasper compilation technology, any repository which + * contains classes from the servlet API will be ignored by the class loader. * <p> - * <strong>IMPLEMENTATION NOTE</strong> - The class loader generates source - * URLs which include the full JAR URL when a class is loaded from a JAR file, - * which allows setting security permission at the class level, even when a - * class is contained inside a JAR. + * <strong>IMPLEMENTATION NOTE</strong> - The class loader generates source URLs which include the full JAR URL when a + * class is loaded from a JAR file, which allows setting security permission at the class level, even when a class is + * contained inside a JAR. * <p> - * <strong>IMPLEMENTATION NOTE</strong> - Local repositories are searched in - * the order they are added via the initial constructor. + * <strong>IMPLEMENTATION NOTE</strong> - Local repositories are searched in the order they are added via the initial + * constructor. * <p> - * <strong>IMPLEMENTATION NOTE</strong> - No check for sealing violations or - * security is made unless a security manager is present. + * <strong>IMPLEMENTATION NOTE</strong> - No check for sealing violations or security is made unless a security manager + * is present. * <p> - * <strong>IMPLEMENTATION NOTE</strong> - As of 8.0, this class - * loader implements {@link InstrumentableClassLoader}, permitting web - * application classes to instrument other classes in the same web - * application. It does not permit instrumentation of system or container - * classes or classes in other web apps. + * <strong>IMPLEMENTATION NOTE</strong> - As of 8.0, this class loader implements {@link InstrumentableClassLoader}, + * permitting web application classes to instrument other classes in the same web application. It does not permit + * instrumentation of system or container classes or classes in other web apps. * * @author Remy Maucherat * @author Craig R. McClanahan @@ -127,8 +118,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader private static final Log log = LogFactory.getLog(WebappClassLoaderBase.class); /** - * List of ThreadGroup names to ignore when scanning for web application - * started threads that need to be shut down. + * List of ThreadGroup names to ignore when scanning for web application started threads that need to be shut down. */ private static final List<String> JVM_THREAD_GROUP_NAMES = new ArrayList<>(); @@ -163,7 +153,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader private final Class<?> clazz; - public PrivilegedGetClassLoader(Class<?> clazz){ + public PrivilegedGetClassLoader(Class<?> clazz) { this.clazz = clazz; } @@ -200,8 +190,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader // ----------------------------------------------------------- Constructors /** - * Construct a new ClassLoader with no defined repositories and no - * parent ClassLoader. + * Construct a new ClassLoader with no defined repositories and no parent ClassLoader. */ protected WebappClassLoaderBase() { @@ -230,11 +219,9 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** - * Construct a new ClassLoader with no defined repositories and the given - * parent ClassLoader. + * Construct a new ClassLoader with no defined repositories and the given parent ClassLoader. * <p> - * Method is used via reflection - - * see {@link WebappLoader#createClassLoader()} + * Method is used via reflection - see {@link WebappLoader#createClassLoader()} * * @param parent Our parent class loader */ @@ -273,24 +260,18 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** - * The cache of ResourceEntry for classes and resources we have loaded, - * keyed by resource path, not binary name. Path is used as the key since - * resources may be requested by binary name (classes) or path (other - * resources such as property files) and the mapping from binary name to - * path is unambiguous but the reverse mapping is ambiguous. + * The cache of ResourceEntry for classes and resources we have loaded, keyed by resource path, not binary name. + * Path is used as the key since resources may be requested by binary name (classes) or path (other resources such + * as property files) and the mapping from binary name to path is unambiguous but the reverse mapping is ambiguous. */ - protected final Map<String, ResourceEntry> resourceEntries = - new ConcurrentHashMap<>(); + protected final Map<String,ResourceEntry> resourceEntries = new ConcurrentHashMap<>(); /** - * Should this class loader delegate to the parent class loader - * <strong>before</strong> searching its own repositories (i.e. the - * usual Java2 delegation model)? If set to <code>false</code>, - * this class loader will search its own repositories first, and - * delegate to the parent only if the class or resource is not - * found locally. Note that the default, <code>false</code>, is - * the behavior called for by the servlet specification. + * Should this class loader delegate to the parent class loader <strong>before</strong> searching its own + * repositories (i.e. the usual Java2 delegation model)? If set to <code>false</code>, this class loader will search + * its own repositories first, and delegate to the parent only if the class or resource is not found locally. Note + * that the default, <code>false</code>, is the behavior called for by the servlet specification. */ protected boolean delegate = false; @@ -299,17 +280,15 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** - * A list of read File Permission's required if this loader is for a web - * application context. + * A list of read File Permission's required if this loader is for a web application context. */ protected final ArrayList<Permission> permissionList = new ArrayList<>(); /** - * The PermissionCollection for each CodeSource for a web - * application context. + * The PermissionCollection for each CodeSource for a web application context. */ - protected final HashMap<String, PermissionCollection> loaderPC = new HashMap<>(); + protected final HashMap<String,PermissionCollection> loaderPC = new HashMap<>(); /** @@ -325,90 +304,77 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** - * The bootstrap class loader used to load the JavaSE classes. In some - * implementations this class loader is always <code>null</code> and in - * those cases {@link ClassLoader#getParent()} will be called recursively on - * the system class loader and the last non-null result used. + * The bootstrap class loader used to load the JavaSE classes. In some implementations this class loader is always + * <code>null</code> and in those cases {@link ClassLoader#getParent()} will be called recursively on the system + * class loader and the last non-null result used. */ private ClassLoader javaseClassLoader; /** - * Enables the RMI Target memory leak detection to be controlled. This is - * necessary since the detection can only work on Java 9 if some of the - * modularity checks are disabled. + * Enables the RMI Target memory leak detection to be controlled. This is necessary since the detection can only + * work on Java 9 if some of the modularity checks are disabled. */ private boolean clearReferencesRmiTargets = true; /** - * Should Tomcat attempt to terminate threads that have been started by the - * web application? Stopping threads is performed via the deprecated (for - * good reason) <code>Thread.stop()</code> method and is likely to result in - * instability. As such, enabling this should be viewed as an option of last - * resort in a development environment and is not recommended in a - * production environment. If not specified, the default value of - * <code>false</code> will be used. + * Should Tomcat attempt to terminate threads that have been started by the web application? Stopping threads is + * performed via the deprecated (for good reason) <code>Thread.stop()</code> method and is likely to result in + * instability. As such, enabling this should be viewed as an option of last resort in a development environment and + * is not recommended in a production environment. If not specified, the default value of <code>false</code> will be + * used. */ private boolean clearReferencesStopThreads = false; /** - * Should Tomcat attempt to terminate any {@link java.util.TimerThread}s - * that have been started by the web application? If not specified, the - * default value of <code>false</code> will be used. + * Should Tomcat attempt to terminate any {@link java.util.TimerThread}s that have been started by the web + * application? If not specified, the default value of <code>false</code> will be used. */ private boolean clearReferencesStopTimerThreads = false; /** - * Should Tomcat call - * {@link org.apache.juli.logging.LogFactory#release(ClassLoader)} when the - * class loader is stopped? If not specified, the default value of - * <code>true</code> is used. Changing the default setting is likely to lead - * to memory leaks and other issues. + * Should Tomcat call {@link org.apache.juli.logging.LogFactory#release(ClassLoader)} when the class loader is + * stopped? If not specified, the default value of <code>true</code> is used. Changing the default setting is likely + * to lead to memory leaks and other issues. */ private boolean clearReferencesLogFactoryRelease = true; /** - * If an HttpClient keep-alive timer thread has been started by this web - * application and is still running, should Tomcat change the context class - * loader from the current {@link ClassLoader} to - * {@link ClassLoader#getParent()} to prevent a memory leak? Note that the - * keep-alive timer thread will stop on its own once the keep-alives all - * expire however, on a busy system that might not happen for some time. + * If an HttpClient keep-alive timer thread has been started by this web application and is still running, should + * Tomcat change the context class loader from the current {@link ClassLoader} to {@link ClassLoader#getParent()} to + * prevent a memory leak? Note that the keep-alive timer thread will stop on its own once the keep-alives all expire + * however, on a busy system that might not happen for some time. */ private boolean clearReferencesHttpClientKeepAliveThread = true; /** - * Should Tomcat attempt to clear references to classes loaded by this class - * loader from the ObjectStreamClass caches? + * Should Tomcat attempt to clear references to classes loaded by this class loader from the ObjectStreamClass + * caches? */ private boolean clearReferencesObjectStreamClassCaches = true; /** - * Should Tomcat attempt to clear references to classes loaded by this class - * loader from ThreadLocals? + * Should Tomcat attempt to clear references to classes loaded by this class loader from ThreadLocals? */ private boolean clearReferencesThreadLocals = true; /** - * Should Tomcat skip the memory leak checks when the web application is - * stopped as part of the process of shutting down the JVM? + * Should Tomcat skip the memory leak checks when the web application is stopped as part of the process of shutting + * down the JVM? */ private boolean skipMemoryLeakChecksOnJvmShutdown = false; /** - * Holds the class file transformers decorating this class loader. The - * CopyOnWriteArrayList is thread safe. It is expensive on writes, but - * those should be rare. It is very fast on reads, since synchronization - * is not actually used. Importantly, the ClassLoader will never block - * iterating over the transformers while loading a class. + * Holds the class file transformers decorating this class loader. The CopyOnWriteArrayList is thread safe. It is + * expensive on writes, but those should be rare. It is very fast on reads, since synchronization is not actually + * used. Importantly, the ClassLoader will never block iterating over the transformers while loading a class. */ private final List<ClassFileTransformer> transformers = new CopyOnWriteArrayList<>(); /** - * Flag that indicates that {@link #addURL(URL)} has been called which - * creates a requirement to check the super class when searching for - * resources. + * Flag that indicates that {@link #addURL(URL)} has been called which creates a requirement to check the super + * class when searching for resources. */ private boolean hasExternalRepositories = false; @@ -439,8 +405,8 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** * Set associated resources. - * @param resources the resources from which the classloader will - * load the classes + * + * @param resources the resources from which the classloader will load the classes */ public void setResources(WebResourceRoot resources) { this.resources = resources; @@ -461,8 +427,9 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** * Return the "delegate first" flag for this class loader. - * @return <code>true</code> if the class lookup will delegate to - * the parent first. The default in Tomcat is <code>false</code>. + * + * @return <code>true</code> if the class lookup will delegate to the parent first. The default in Tomcat is + * <code>false</code>. */ public boolean getDelegate() { return this.delegate; @@ -470,15 +437,11 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** - * Set the "delegate first" flag for this class loader. - * If this flag is true, this class loader delegates - * to the parent class loader - * <strong>before</strong> searching its own repositories, as - * in an ordinary (non-servlet) chain of Java class loaders. - * If set to <code>false</code> (the default), - * this class loader will search its own repositories first, and - * delegate to the parent only if the class or resource is not - * found locally, as per the servlet specification. + * Set the "delegate first" flag for this class loader. If this flag is true, this class loader delegates to the + * parent class loader <strong>before</strong> searching its own repositories, as in an ordinary (non-servlet) chain + * of Java class loaders. If set to <code>false</code> (the default), this class loader will search its own + * repositories first, and delegate to the parent only if the class or resource is not found locally, as per the + * servlet specification. * * @param delegate The new "delegate first" flag */ @@ -488,8 +451,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** - * If there is a Java SecurityManager create a read permission for the - * target of the given URL as appropriate. + * If there is a Java SecurityManager create a read permission for the target of the given URL as appropriate. * * @param url URL for a file or directory on local system */ @@ -508,9 +470,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader f = new File(uri); path = f.getCanonicalPath(); } catch (IOException | URISyntaxException e) { - log.warn(sm.getString( - "webappClassLoader.addPermissionNoCanonicalFile", - url.toExternalForm())); + log.warn(sm.getString("webappClassLoader.addPermissionNoCanonicalFile", url.toExternalForm())); return; } if (f.isFile()) { @@ -518,16 +478,13 @@ public abstract class WebappClassLoaderBase extends URLClassLoader addPermission(new FilePermission(path, "read")); } else if (f.isDirectory()) { addPermission(new FilePermission(path, "read")); - addPermission(new FilePermission( - path + File.separator + "-", "read")); + addPermission(new FilePermission(path + File.separator + "-", "read")); } else { // File does not exist - ignore (shouldn't happen) } } else { // Unsupported URL protocol - log.warn(sm.getString( - "webappClassLoader.addPermissionNoProtocol", - protocol, url.toExternalForm())); + log.warn(sm.getString("webappClassLoader.addPermissionNoProtocol", protocol, url.toExternalForm())); } } } @@ -539,7 +496,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader * @param permission The permission */ void addPermission(Permission permission) { - if ((securityManager != null) && (permission != null)) { + if (securityManager != null && permission != null) { permissionList.add(permission); } } @@ -568,8 +525,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader * * @param clearReferencesStopThreads The new flag value */ - public void setClearReferencesStopThreads( - boolean clearReferencesStopThreads) { + public void setClearReferencesStopThreads(boolean clearReferencesStopThreads) { this.clearReferencesStopThreads = clearReferencesStopThreads; } @@ -587,8 +543,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader * * @param clearReferencesStopTimerThreads The new flag value */ - public void setClearReferencesStopTimerThreads( - boolean clearReferencesStopTimerThreads) { + public void setClearReferencesStopTimerThreads(boolean clearReferencesStopTimerThreads) { this.clearReferencesStopTimerThreads = clearReferencesStopTimerThreads; } @@ -606,16 +561,13 @@ public abstract class WebappClassLoaderBase extends URLClassLoader * * @param clearReferencesLogFactoryRelease The new flag value */ - public void setClearReferencesLogFactoryRelease( - boolean clearReferencesLogFactoryRelease) { - this.clearReferencesLogFactoryRelease = - clearReferencesLogFactoryRelease; + public void setClearReferencesLogFactoryRelease(boolean clearReferencesLogFactoryRelease) { + this.clearReferencesLogFactoryRelease = clearReferencesLogFactoryRelease; } /** - * @return the clearReferencesHttpClientKeepAliveThread flag for this - * Context. + * @return the clearReferencesHttpClientKeepAliveThread flag for this Context. */ public boolean getClearReferencesHttpClientKeepAliveThread() { return this.clearReferencesHttpClientKeepAliveThread; @@ -623,15 +575,12 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** - * Set the clearReferencesHttpClientKeepAliveThread feature for this - * Context. + * Set the clearReferencesHttpClientKeepAliveThread feature for this Context. * * @param clearReferencesHttpClientKeepAliveThread The new flag value */ - public void setClearReferencesHttpClientKeepAliveThread( - boolean clearReferencesHttpClientKeepAliveThread) { - this.clearReferencesHttpClientKeepAliveThread = - clearReferencesHttpClientKeepAliveThread; + public void setClearReferencesHttpClientKeepAliveThread(boolean clearReferencesHttpClientKeepAliveThread) { + this.clearReferencesHttpClientKeepAliveThread = clearReferencesHttpClientKeepAliveThread; } @@ -640,8 +589,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader } - public void setClearReferencesObjectStreamClassCaches( - boolean clearReferencesObjectStreamClassCaches) { + public void setClearReferencesObjectStreamClassCaches(boolean clearReferencesObjectStreamClassCaches) { this.clearReferencesObjectStreamClassCaches = clearReferencesObjectStreamClassCaches; } @@ -669,9 +617,8 @@ public abstract class WebappClassLoaderBase extends URLClassLoader // ------------------------------------------------------- Reloader Methods /** - * Adds the specified class file transformer to this class loader. The - * transformer will then be able to modify the bytecode of any classes - * loaded by this class loader after the invocation of this method. + * Adds the specified class file transformer to this class loader. The transformer will then be able to modify the + * bytecode of any classes loaded by this class loader after the invocation of this method. * * @param transformer The transformer to add to the class loader */ @@ -679,14 +626,13 @@ public abstract class WebappClassLoaderBase extends URLClassLoader public void addTransformer(ClassFileTransformer transformer) { if (transformer == null) { - throw new IllegalArgumentException(sm.getString( - "webappClassLoader.addTransformer.illegalArgument", getContextName())); + throw new IllegalArgumentException( + sm.getString("webappClassLoader.addTransformer.illegalArgument", getContextName())); } if (this.transformers.contains(transformer)) { // if the same instance of this transformer was already added, bail out - log.warn(sm.getString("webappClassLoader.addTransformer.duplicate", - transformer, getContextName())); + log.warn(sm.getString("webappClassLoader.addTransformer.duplicate", transformer, getContextName())); return; } this.transformers.add(transformer); @@ -695,11 +641,9 @@ public abstract class WebappClassLoaderBase extends URLClassLoader } /** - * Removes the specified class file transformer from this class loader. - * It will no longer be able to modify the byte code of any classes - * loaded by the class loader after the invocation of this method. - * However, any classes already modified by this transformer will - * remain transformed. + * Removes the specified class file transformer from this class loader. It will no longer be able to modify the byte + * code of any classes loaded by the class loader after the invocation of this method. However, any classes already + * modified by this transformer will remain transformed. * * @param transformer The transformer to remove */ @@ -711,8 +655,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader } if (this.transformers.remove(transformer)) { - log.info(sm.getString("webappClassLoader.removeTransformer", - transformer, getContextName())); + log.info(sm.getString("webappClassLoader.removeTransformer", transformer, getContextName())); } } @@ -730,8 +673,8 @@ public abstract class WebappClassLoaderBase extends URLClassLoader } /** - * Have one or more classes or resources been modified so that a reload - * is appropriate? + * Have one or more classes or resources been modified so that a reload is appropriate? + * * @return <code>true</code> if there's been a modification */ public boolean modified() { @@ -742,14 +685,11 @@ public abstract class WebappClassLoaderBase extends URLClassLoader for (Entry<String,ResourceEntry> entry : resourceEntries.entrySet()) { long cachedLastModified = entry.getValue().lastModified; - long lastModified = resources.getClassLoaderResource( - entry.getKey()).getLastModified(); + long lastModified = resources.getClassLoaderResource(entry.getKey()).getLastModified(); if (lastModified != cachedLastModified) { - if( log.isDebugEnabled() ) { - log.debug(sm.getString("webappClassLoader.resourceModified", - entry.getKey(), - new Date(cachedLastModified), - new Date(lastModified))); + if (log.isDebugEnabled()) { + log.debug(sm.getString("webappClassLoader.resourceModified", entry.getKey(), + new Date(cachedLastModified), new Date(lastModified))); } return true; } @@ -766,22 +706,19 @@ public abstract class WebappClassLoaderBase extends URLClassLoader Long recordedLastModified = jarModificationTimes.get(jar.getName()); if (recordedLastModified == null) { // Jar has been added - log.info(sm.getString("webappClassLoader.jarsAdded", - resources.getContext().getName())); + log.info(sm.getString("webappClassLoader.jarsAdded", resources.getContext().getName())); return true; } if (recordedLastModified.longValue() != jar.getLastModified()) { // Jar has been changed - log.info(sm.getString("webappClassLoader.jarsModified", - resources.getContext().getName())); + log.info(sm.getString("webappClassLoader.jarsModified", resources.getContext().getName())); return true; } } } - if (jarCount < jarModificationTimes.size()){ - log.info(sm.getString("webappClassLoader.jarsRemoved", - resources.getContext().getName())); + if (jarCount < jarModificationTimes.size()) { + log.info(sm.getString("webappClassLoader.jarsRemoved", resources.getContext().getName())); return true; } @@ -819,14 +756,13 @@ public abstract class WebappClassLoaderBase extends URLClassLoader // Note: exposed for use by tests - protected final Class<?> doDefineClass(String name, byte[] b, int off, int len, - ProtectionDomain protectionDomain) { + protected final Class<?> doDefineClass(String name, byte[] b, int off, int len, ProtectionDomain protectionDomain) { return super.defineClass(name, b, off, len, protectionDomain); } /** - * Find the specified class in our local repositories, if possible. If - * not found, throw <code>ClassNotFoundException</code>. + * Find the specified class in our local repositories, if possible. If not found, throw + * <code>ClassNotFoundException</code>. * * @param name The binary name of the class to be loaded * @@ -849,7 +785,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader if (log.isTraceEnabled()) { log.trace(" securityManager.checkPackageDefinition"); } - securityManager.checkPackageDefinition(name.substring(0,i)); + securityManager.checkPackageDefinition(name.substring(0, i)); } catch (Exception se) { if (log.isTraceEnabled()) { log.trace(" -->Exception-->ClassNotFoundException", se); @@ -868,15 +804,13 @@ public abstract class WebappClassLoaderBase extends URLClassLoader } try { if (securityManager != null) { - PrivilegedAction<Class<?>> dp = - new PrivilegedFindClassByName(name); + PrivilegedAction<Class<?>> dp = new PrivilegedFindClassByName(name); clazz = AccessController.doPrivileged(dp); } else { clazz = findClassInternal(name); } - } catch(AccessControlException ace) { - log.warn(sm.getString("webappClassLoader.securityException", name, - ace.getMessage()), ace); + } catch (AccessControlException ace) { + log.warn(sm.getString("webappClassLoader.securityException", name, ace.getMessage()), ace); throw new ClassNotFoundException(name, ace); } catch (RuntimeException e) { if (log.isTraceEnabled()) { @@ -884,12 +818,11 @@ public abstract class WebappClassLoaderBase extends URLClassLoader } throw e; } - if ((clazz == null) && hasExternalRepositories) { + if (clazz == null && hasExternalRepositories) { try { clazz = super.findClass(name); - } catch(AccessControlException ace) { - log.warn(sm.getString("webappClassLoader.securityException", name, - ace.getMessage()), ace); + } catch (AccessControlException ace) { + log.warn(sm.getString("webappClassLoader.securityException", name, ace.getMessage()), ace); throw new ClassNotFoundException(name, ace); } catch (RuntimeException e) { if (log.isTraceEnabled()) { @@ -918,9 +851,8 @@ public abstract class WebappClassLoaderBase extends URLClassLoader if (log.isTraceEnabled()) { ClassLoader cl; - if (Globals.IS_SECURITY_ENABLED){ - cl = AccessController.doPrivileged( - new PrivilegedGetClassLoader(clazz)); + if (Globals.IS_SECURITY_ENABLED) { + cl = AccessController.doPrivileged(new PrivilegedGetClassLoader(clazz)); } else { cl = clazz.getClassLoader(); } @@ -932,9 +864,8 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** - * Find the specified resource in our local repository, and return a - * <code>URL</code> referring to it, or <code>null</code> if this resource - * cannot be found. + * Find the specified resource in our local repository, and return a <code>URL</code> referring to it, or + * <code>null</code> if this resource cannot be found. * * @param name Name of the resource to be found */ @@ -957,7 +888,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader trackLastModified(path, resource); } - if ((url == null) && hasExternalRepositories) { + if (url == null && hasExternalRepositories) { url = super.findResource(name); } @@ -978,16 +909,15 @@ public abstract class WebappClassLoaderBase extends URLClassLoader } ResourceEntry entry = new ResourceEntry(); entry.lastModified = resource.getLastModified(); - synchronized(resourceEntries) { + synchronized (resourceEntries) { resourceEntries.putIfAbsent(path, entry); } } /** - * Return an enumeration of <code>URLs</code> representing all of the - * resources with the given name. If no resources with this name are - * found, return an empty enumeration. + * Return an enumeration of <code>URLs</code> representing all of the resources with the given name. If no resources + * with this name are found, return an empty enumeration. * * @param name Name of the resources to be found * @@ -1026,23 +956,17 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** - * Find the resource with the given name. A resource is some data - * (images, audio, text, etc.) that can be accessed by class code in a - * way that is independent of the location of the code. The name of a - * resource is a "/"-separated path name that identifies the resource. - * If the resource cannot be found, return <code>null</code>. + * Find the resource with the given name. A resource is some data (images, audio, text, etc.) that can be accessed + * by class code in a way that is independent of the location of the code. The name of a resource is a "/"-separated + * path name that identifies the resource. If the resource cannot be found, return <code>null</code>. * <p> - * This method searches according to the following algorithm, returning - * as soon as it finds the appropriate URL. If the resource cannot be - * found, returns <code>null</code>. + * This method searches according to the following algorithm, returning as soon as it finds the appropriate URL. If + * the resource cannot be found, returns <code>null</code>. * <ul> - * <li>If the <code>delegate</code> property is set to <code>true</code>, - * call the <code>getResource()</code> method of the parent class - * loader, if any.</li> - * <li>Call <code>findResource()</code> to find this resource in our - * locally defined repositories.</li> - * <li>Call the <code>getResource()</code> method of the parent class - * loader, if any.</li> + * <li>If the <code>delegate</code> property is set to <code>true</code>, call the <code>getResource()</code> method + * of the parent class loader, if any.</li> + * <li>Call <code>findResource()</code> to find this resource in our locally defined repositories.</li> + * <li>Call the <code>getResource()</code> method of the parent class loader, if any.</li> * </ul> * * @param name Name of the resource to return a URL for @@ -1122,11 +1046,9 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** - * Find the resource with the given name, and return an input stream - * that can be used for reading it. The search order is as described - * for <code>getResource()</code>, after checking to see if the resource - * data has been previously cached. If the resource cannot be found, - * return <code>null</code>. + * Find the resource with the given name, and return an input stream that can be used for reading it. The search + * order is as described for <code>getResource()</code>, after checking to see if the resource data has been + * previously cached. If the resource cannot be found, return <code>null</code>. * * @param name Name of the resource to return an input stream for */ @@ -1207,9 +1129,8 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** - * Load the class with the specified name. This method searches for - * classes in the same manner as <code>loadClass(String, boolean)</code> - * with <code>false</code> as the second argument. + * Load the class with the specified name. This method searches for classes in the same manner as + * <code>loadClass(String, boolean)</code> with <code>false</code> as the second argument. * * @param name The binary name of the class to be loaded * @@ -1222,26 +1143,20 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** - * Load the class with the specified name, searching using the following - * algorithm until it finds and returns the class. If the class cannot - * be found, returns <code>ClassNotFoundException</code>. + * Load the class with the specified name, searching using the following algorithm until it finds and returns the + * class. If the class cannot be found, returns <code>ClassNotFoundException</code>. * <ul> - * <li>Call <code>findLoadedClass(String)</code> to check if the - * class has already been loaded. If it has, the same - * <code>Class</code> object is returned.</li> - * <li>If the <code>delegate</code> property is set to <code>true</code>, - * call the <code>loadClass()</code> method of the parent class - * loader, if any.</li> - * <li>Call <code>findClass()</code> to find this class in our locally - * defined repositories.</li> - * <li>Call the <code>loadClass()</code> method of our parent - * class loader, if any.</li> + * <li>Call <code>findLoadedClass(String)</code> to check if the class has already been loaded. If it has, the same + * <code>Class</code> object is returned.</li> + * <li>If the <code>delegate</code> property is set to <code>true</code>, call the <code>loadClass()</code> method + * of the parent class loader, if any.</li> + * <li>Call <code>findClass()</code> to find this class in our locally defined repositories.</li> + * <li>Call the <code>loadClass()</code> method of our parent class loader, if any.</li> * </ul> - * If the class was found using the above steps, and the - * <code>resolve</code> flag is <code>true</code>, this method will then - * call <code>resolveClass(Class)</code> on the resulting Class object. + * If the class was found using the above steps, and the <code>resolve</code> flag is <code>true</code>, this method + * will then call <code>resolveClass(Class)</code> on the resulting Class object. * - * @param name The binary name of the class to be loaded + * @param name The binary name of the class to be loaded * @param resolve If <code>true</code> then resolve the class * * @exception ClassNotFoundException if the class was not found @@ -1282,24 +1197,26 @@ public abstract class WebappClassLoaderBase extends URLClassLoader return clazz; } - // (0.2) Try loading the class with the bootstrap class loader, to prevent - // the webapp from overriding Java SE classes. This implements - // SRV.10.7.2 + /* + * (0.2) Try loading the class with the bootstrap class loader, to prevent the webapp from overriding Java + * SE classes. This implements SRV.10.7.2 + */ String resourceName = binaryNameToPath(name, false); ClassLoader javaseLoader = getJavaseClassLoader(); boolean tryLoadingFromJavaseLoader; try { - // Use getResource as it won't trigger an expensive - // ClassNotFoundException if the resource is not available from - // the Java SE class loader. However (see - // https://bz.apache.org/bugzilla/show_bug.cgi?id=58125 for - // details) when running under a security manager in rare cases - // this call may trigger a ClassCircularityError. - // See https://bz.apache.org/bugzilla/show_bug.cgi?id=61424 for - // details of how this may trigger a StackOverflowError - // Given these reported errors, catch Throwable to ensure any - // other edge cases are also caught + /* + * Use getResource as it won't trigger an expensive ClassNotFoundException if the resource is not + * available from the Java SE class loader. However (see + * https://bz.apache.org/bugzilla/show_bug.cgi?id=58125 for details) when running under a security + * manager in rare cases this call may trigger a ClassCircularityError. + * + * See https://bz.apache.org/bugzilla/show_bug.cgi?id=61424 for details of how this may trigger a + * StackOverflowError. + * + * Given these reported errors, catch Throwable to ensure all edge cases are caught. + */ URL url; if (securityManager != null) { PrivilegedAction<URL> dp = new PrivilegedJavaseGetResource(resourceName); @@ -1307,7 +1224,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader } else { url = javaseLoader.getResource(resourceName); } - tryLoadingFromJavaseLoader = (url != null); + tryLoadingFromJavaseLoader = url != null; } catch (Throwable t) { // Swallow all exceptions apart from those that must be re-thrown ExceptionUtils.handleThrowable(t); @@ -1336,7 +1253,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader int i = name.lastIndexOf('.'); if (i >= 0) { try { - securityManager.checkPackageAccess(name.substring(0,i)); + securityManager.checkPackageAccess(name.substring(0, i)); } catch (SecurityException se) { String error = sm.getString("webappClassLoader.restrictedPackage", name); log.info(error, se); @@ -1436,11 +1353,11 @@ public abstract class WebappClassLoaderBase extends URLClassLoader } /** - * Get the Permissions for a CodeSource. If this instance - * of WebappClassLoaderBase is for a web application context, + * Get the Permissions for a CodeSource. If this instance of WebappClassLoaderBase is for a web application context, * add read FilePermission for the appropriate resources. * * @param codeSource where the code was loaded from + * * @return PermissionCollection for CodeSource */ @Override @@ -1453,7 +1370,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader for (Permission p : permissionList) { pc.add(p); } - loaderPC.put(codeUrl,pc); + loaderPC.put(codeUrl, pc); } } return pc; @@ -1481,11 +1398,9 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** * {@inheritDoc} * <p> - * Note that list of URLs returned by this method may not be complete. The - * web application class loader accesses class loader resources via the - * {@link WebResourceRoot} which supports the arbitrary mapping of - * additional files, directories and contents of JAR files under - * WEB-INF/classes. Any such resources will not be included in the URLs + * Note that list of URLs returned by this method may not be complete. The web application class loader accesses + * class loader resources via the {@link WebResourceRoot} which supports the arbitrary mapping of additional files, + * directories and contents of JAR files under WEB-INF/classes. Any such resources will not be included in the URLs * returned here. */ @Override @@ -1512,8 +1427,8 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** - * Get the lifecycle listeners associated with this lifecycle. If this - * Lifecycle has no listeners registered, a zero-length array is returned. + * Get the lifecycle listeners associated with this lifecycle. If this Lifecycle has no listeners registered, a + * zero-length array is returned. */ @Override public LifecycleListener[] findLifecycleListeners() { @@ -1575,8 +1490,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader for (WebResource jar : jars) { if (jar.getName().endsWith(".jar") && jar.isFile() && jar.canRead()) { localRepositories.add(jar.getURL()); - jarModificationTimes.put( - jar.getName(), Long.valueOf(jar.getLastModified())); + jarModificationTimes.put(jar.getName(), Long.valueOf(jar.getLastModified())); } } @@ -1632,8 +1546,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader protected void setJavaseClassLoader(ClassLoader classLoader) { if (classLoader == null) { - throw new IllegalArgumentException( - sm.getString("webappClassLoader.javaseClassLoaderNull")); + throw new IllegalArgumentException(sm.getString("webappClassLoader.javaseClassLoaderNull")); } javaseClassLoader = classLoader; } @@ -1644,8 +1557,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader protected void clearReferences() { // If the JVM is shutting down, skip the memory leak checks - if (skipMemoryLeakChecksOnJvmShutdown - && !resources.getContext().getParent().getState().isAvailable()) { + if (skipMemoryLeakChecksOnJvmShutdown && !resources.getContext().getParent().getState().isAvailable()) { // During reloading / redeployment the parent is expected to be // available. Parent is not available so this might be a JVM // shutdown. @@ -1681,7 +1593,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader clearReferencesRmiTargets(); } - // Clear the IntrospectionUtils cache. + // Clear the IntrospectionUtils cache. IntrospectionUtils.clear(); // Clear the classloader reference in common-logging @@ -1698,21 +1610,16 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** - * Deregister any JDBC drivers registered by the webapp that the webapp - * forgot. This is made unnecessary complex because a) DriverManager - * checks the class loader of the calling class (it would be much easier - * if it checked the context class loader) b) using reflection would - * create a dependency on the DriverManager implementation which can, - * and has, changed. - * - * We can't just create an instance of JdbcLeakPrevention as it will be - * loaded by the common class loader (since it's .class file is in the - * $CATALINA_HOME/lib directory). This would fail DriverManager's check - * on the class loader of the calling class. So, we load the bytes via - * our parent class loader but define the class with this class loader - * so the JdbcLeakPrevention looks like a webapp class to the - * DriverManager. - * + * Deregister any JDBC drivers registered by the webapp that the webapp forgot. This is made unnecessary complex + * because a) DriverManager checks the class loader of the calling class (it would be much easier if it checked the + * context class loader) b) using reflection would create a dependency on the DriverManager implementation which + * can, and has, changed. + * <p> + * We can't just create an instance of JdbcLeakPrevention as it will be loaded by the common class loader (since + * it's .class file is in the $CATALINA_HOME/lib directory). This would fail DriverManager's check on the class + * loader of the calling class. So, we load the bytes via our parent class loader but define the class with this + * class loader so the JdbcLeakPrevention looks like a webapp class to the DriverManager. + * <p> * If only apps cleaned up after themselves... */ private void clearReferencesJdbc() { @@ -1720,9 +1627,8 @@ public abstract class WebappClassLoaderBase extends URLClassLoader // starting point byte[] classBytes = new byte[2048]; int offset = 0; - try (InputStream is = getResourceAsStream( - "org/apache/catalina/loader/JdbcLeakPrevention.class")) { - int read = is.read(classBytes, offset, classBytes.length-offset); + try (InputStream is = getResourceAsStream("org/apache/catalina/loader/JdbcLeakPrevention.class")) { + int read = is.read(classBytes, offset, classBytes.length - offset); while (read > -1) { offset += read; if (offset == classBytes.length) { @@ -1731,25 +1637,22 @@ public abstract class WebappClassLoaderBase extends URLClassLoader System.arraycopy(classBytes, 0, tmp, 0, classBytes.length); classBytes = tmp; } - read = is.read(classBytes, offset, classBytes.length-offset); + read = is.read(classBytes, offset, classBytes.length - offset); } - Class<?> lpClass = - defineClass("org.apache.catalina.loader.JdbcLeakPrevention", - classBytes, 0, offset, this.getClass().getProtectionDomain()); + Class<?> lpClass = defineClass("org.apache.catalina.loader.JdbcLeakPrevention", classBytes, 0, offset, + this.getClass().getProtectionDomain()); Object obj = lpClass.getConstructor().newInstance(); @SuppressWarnings("unchecked") - List<String> driverNames = (List<String>) obj.getClass().getMethod( - "clearJdbcDriverRegistrations").invoke(obj); + List<String> driverNames = + (List<String>) obj.getClass().getMethod("clearJdbcDriverRegistrations").invoke(obj); for (String name : driverNames) { - log.warn(sm.getString("webappClassLoader.clearJdbc", - getContextName(), name)); + log.warn(sm.getString("webappClassLoader.clearJdbc", getContextName(), name)); } } catch (Exception e) { // So many things to go wrong above... Throwable t = ExceptionUtils.unwrapInvocationTargetException(e); ExceptionUtils.handleThrowable(t); - log.warn(sm.getString( - "webappClassLoader.jdbcRemoveFailed", getContextName()), t); + log.warn(sm.getString("webappClassLoader.jdbcRemoveFailed", getContextName()), t); } } @@ -1775,8 +1678,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader ThreadGroup tg = thread.getThreadGroup(); if (tg != null && JVM_THREAD_GROUP_NAMES.contains(tg.getName())) { // HttpClient keep-alive threads - if (clearReferencesHttpClientKeepAliveThread && - threadName.equals("Keep-Alive-Timer")) { + if (clearReferencesHttpClientKeepAliveThread && threadName.equals("Keep-Alive-Timer")) { thread.setContextClassLoader(parent); log.debug(sm.getString("webappClassLoader.checkThreadsHttpClient")); } @@ -1793,18 +1695,17 @@ public abstract class WebappClassLoaderBase extends URLClassLoader // TimerThread can be stopped safely so treat separately // "java.util.TimerThread" in Sun/Oracle JDK // "java.util.Timer$TimerImpl" in Apache Harmony and in IBM JDK - if (thread.getClass().getName().startsWith("java.util.Timer") && - clearReferencesStopTimerThreads) { + if (thread.getClass().getName().startsWith("java.util.Timer") && clearReferencesStopTimerThreads) { clearReferencesStopTimerThread(thread); continue; } if (isRequestThread(thread)) { - log.warn(sm.getString("webappClassLoader.stackTraceRequestThread", - getContextName(), threadName, getStackTrace(thread))); + log.warn(sm.getString("webappClassLoader.stackTraceRequestThread", getContextName(), threadName, + getStackTrace(thread))); } else { - log.warn(sm.getString("webappClassLoader.stackTrace", - getContextName(), threadName, getStackTrace(thread))); + log.warn(sm.getString("webappClassLoader.stackTrace", getContextName(), threadName, + getStackTrace(thread))); } // Don't try and stop the threads unless explicitly @@ -1828,8 +1729,8 @@ public abstract class WebappClassLoaderBase extends URLClassLoader } catch (NoSuchFieldException | IllegalAccessException | RuntimeException e) { // InaccessibleObjectException is only available in Java 9+, // swapped for RuntimeException - log.warn(sm.getString("webappClassLoader.stopThreadFail", - thread.getName(), getContextName()), e); + log.warn(sm.getString("webappClassLoader.stopThreadFail", thread.getName(), getContextName()), + e); } // Stopping an executor automatically interrupts the @@ -1876,8 +1777,8 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /* - * Look at a threads stack trace to see if it is a request thread or not. It - * isn't perfect, but it should be good-enough for most cases. + * Look at a threads stack trace to see if it is a request thread or not. It isn't perfect, but it should be + * good-enough for most cases. */ private boolean isRequestThread(Thread thread) { @@ -1894,9 +1795,8 @@ public abstract class WebappClassLoaderBase extends URLClassLoader // Tomcat has been heavily modified - in which case there isn't much we // can do. for (int i = 0; i < elements.length; i++) { - StackTraceElement element = elements[elements.length - (i+1)]; - if ("org.apache.catalina.connector.CoyoteAdapter".equals( - element.getClassName())) { + StackTraceElement element = elements[elements.length - (i + 1)]; + if ("org.apache.catalina.connector.CoyoteAdapter".equals(element.getClassName())) { return true; } } @@ -1917,8 +1817,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader try { try { - Field newTasksMayBeScheduledField = - thread.getClass().getDeclaredField("newTasksMayBeScheduled"); + Field newTasksMayBeScheduledField = thread.getClass().getDeclaredField("newTasksMayBeScheduled"); newTasksMayBeScheduledField.setAccessible(true); Field queueField = thread.getClass().getDeclaredField("queue"); queueField.setAccessible(true); @@ -1928,7 +1827,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader Method clearMethod = queue.getClass().getDeclaredMethod("clear"); clearMethod.setAccessible(true); - synchronized(queue) { + synchronized (queue) { newTasksMayBeScheduledField.setBoolean(thread, false); clearMethod.invoke(queue); // In case queue was already empty. Should only be one @@ -1936,24 +1835,21 @@ public abstract class WebappClassLoaderBase extends URLClassLoader queue.notifyAll(); } - }catch (NoSuchFieldException nfe){ + } catch (NoSuchFieldException nfe) { Method cancelMethod = thread.getClass().getDeclaredMethod("cancel"); - synchronized(thread) { + synchronized (thread) { cancelMethod.setAccessible(true); cancelMethod.invoke(thread); } } - log.warn(sm.getString("webappClassLoader.warnTimerThread", - getContextName(), thread.getName())); + log.warn(sm.getString("webappClassLoader.warnTimerThread", getContextName(), thread.getName())); } catch (Exception e) { // So many things to go wrong above... Throwable t = ExceptionUtils.unwrapInvocationTargetException(e); ExceptionUtils.handleThrowable(t); - log.warn(sm.getString( - "webappClassLoader.stopTimerThreadFail", - thread.getName(), getContextName()), t); + log.warn(sm.getString("webappClassLoader.stopTimerThreadFail", thread.getName(), getContextName()), t); } } @@ -1963,11 +1859,9 @@ public abstract class WebappClassLoaderBase extends URLClassLoader try { // Make the fields in the Thread class that store ThreadLocals // accessible - Field threadLocalsField = - Thread.class.getDeclaredField("threadLocals"); + Field threadLocalsField = Thread.class.getDeclaredField("threadLocals"); threadLocalsField.setAccessible(true); - Field inheritableThreadLocalsField = - Thread.class.getDeclaredField("inheritableThreadLocals"); + Field inheritableThreadLocalsField = Thread.class.getDeclaredField("inheritableThreadLocals"); inheritableThreadLocalsField.setAccessible(true); // Make the underlying array of ThreadLoad.ThreadLocalMap.Entry objects // accessible @@ -2005,22 +1899,18 @@ public abstract class WebappClassLoaderBase extends URLClassLoader log.warn(sm.getString("webappClassLoader.addExportsThreadLocal", currentModule)); } else { ExceptionUtils.handleThrowable(t); - log.warn(sm.getString( - "webappClassLoader.checkThreadLocalsForLeaksFail", - getContextName()), t); + log.warn(sm.getString("webappClassLoader.checkThreadLocalsForLeaksFail", getContextName()), t); } } } /** - * Analyzes the given thread local map object. Also pass in the field that - * points to the internal table to save re-calculating it on every - * call to this method. + * Analyzes the given thread local map object. Also pass in the field that points to the internal table to save + * re-calculating it on every call to this method. */ - private void checkThreadLocalMapForLeaks(Object map, - Field internalTableField) throws IllegalAccessException, - NoSuchFieldException { + private void checkThreadLocalMapForLeaks(Object map, Field internalTableField) + throws IllegalAccessException, NoSuchFieldException { if (map != null) { Object[] table = (Object[]) internalTableField.get(map); if (table != null) { @@ -2034,8 +1924,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader keyLoadedByWebapp = true; } // Check the value - Field valueField = - obj.getClass().getDeclaredField("value"); + Field valueField = obj.getClass().getDeclaredField("value"); valueField.setAccessible(true); Object value = valueField.get(obj); if (this.equals(value) || loadedByThisOrChild(value)) { @@ -2049,11 +1938,10 @@ public abstract class WebappClassLoaderBase extends URLClassLoader try { args[2] = key.toString(); } catch (Exception e) { - log.warn(sm.getString( - "webappClassLoader.checkThreadLocalsForLeaks.badKey", - args[1]), e); - args[2] = sm.getString( - "webappClassLoader.checkThreadLocalsForLeaks.unknown"); + log.warn( + sm.getString("webappClassLoader.checkThreadLocalsForLeaks.badKey", args[1]), + e); + args[2] = sm.getString("webappClassLoader.checkThreadLocalsForLeaks.unknown"); } } if (value != null) { @@ -2061,28 +1949,20 @@ public abstract class WebappClassLoaderBase extends URLClassLoader try { args[4] = value.toString(); } catch (Exception e) { - log.warn(sm.getString( - "webappClassLoader.checkThreadLocalsForLeaks.badValue", + log.warn(sm.getString("webappClassLoader.checkThreadLocalsForLeaks.badValue", args[3]), e); - args[4] = sm.getString( - "webappClassLoader.checkThreadLocalsForLeaks.unknown"); + args[4] = sm.getString("webappClassLoader.checkThreadLocalsForLeaks.unknown"); } } if (valueLoadedByWebapp) { - log.error(sm.getString( - "webappClassLoader.checkThreadLocalsForLeaks", - args)); + log.error(sm.getString("webappClassLoader.checkThreadLocalsForLeaks", args)); } else if (value == null) { if (log.isDebugEnabled()) { - log.debug(sm.getString( - "webappClassLoader.checkThreadLocalsForLeaksNull", - args)); + log.debug(sm.getString("webappClassLoader.checkThreadLocalsForLeaksNull", args)); } } else { if (log.isDebugEnabled()) { - log.debug(sm.getString( - "webappClassLoader.checkThreadLocalsForLeaksNone", - args)); + log.debug(sm.getString("webappClassLoader.checkThreadLocalsForLeaksNone", args)); } } } @@ -2094,7 +1974,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader private String getPrettyClassName(Class<?> clazz) { String name = clazz.getCanonicalName(); - if (name==null){ + if (name == null) { name = clazz.getName(); } return name; @@ -2110,8 +1990,8 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** * @param o object to test, may be null - * @return <code>true</code> if o has been loaded by the current classloader - * or one of its descendants. + * + * @return <code>true</code> if o has been loaded by the current classloader or one of its descendants. */ private boolean loadedByThisOrChild(Object o) { if (o == null) { @@ -2135,14 +2015,13 @@ public abstract class WebappClassLoaderBase extends URLClassLoader if (o instanceof Collection<?>) { try { - for (Object entry : ((Collection<?>) o)) { + for (Object entry : (Collection<?>) o) { if (loadedByThisOrChild(entry)) { return true; } } } catch (ConcurrentModificationException e) { - log.warn(sm.getString( - "webappClassLoader.loadedByThisOrChildFail", clazz.getName(), getContextName()), + log.warn(sm.getString("webappClassLoader.loadedByThisOrChildFail", clazz.getName(), getContextName()), e); } } @@ -2161,8 +2040,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader tg = tg.getParent(); } } catch (SecurityException se) { - String msg = sm.getString( - "webappClassLoader.getThreadGroupError", tg.getName()); + String msg = sm.getString("webappClassLoader.getThreadGroupError", tg.getName()); if (log.isDebugEnabled()) { log.debug(msg, se); } else { @@ -2175,7 +2053,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader int threadCountActual = tg.enumerate(threads); // Make sure we don't miss any threads while (threadCountActual == threadCountGuess) { - threadCountGuess *=2; + threadCountGuess *= 2; threads = new Thread[threadCountGuess]; // Note tg.enumerate(Thread[]) silently ignores any threads that // can't fit into the array @@ -2187,15 +2065,13 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** - * This depends on the internals of the Sun JVM so it does everything by - * reflection. + * This depends on the internals of the Sun JVM so it does everything by reflection. */ private void clearReferencesRmiTargets() { try { // Need access to the ccl field of sun.rmi.transport.Target to find // the leaks - Class<?> objectTargetClass = - Class.forName("sun.rmi.transport.Target"); + Class<?> objectTargetClass = Class.forName("sun.rmi.transport.Target"); Field cclField = objectTargetClass.getDeclaredField("ccl"); cclField.setAccessible(true); // Need access to the stub field to report the leaks @@ -2224,8 +2100,8 @@ public abstract class WebappClassLoaderBase extends URLClassLoader if (this == cclObject) { iter.remove(); Object stubObject = stubField.get(obj); - log.error(sm.getString("webappClassLoader.clearRmi", - stubObject.getClass().getName(), stubObject)); + log.error(sm.getString("webappClassLoader.clearRmi", stubObject.getClass().getName(), + stubObject)); } } } @@ -2251,12 +2127,9 @@ public abstract class WebappClassLoaderBase extends URLClassLoader } } } catch (ClassNotFoundException e) { - log.info(sm.getString("webappClassLoader.clearRmiInfo", - getContextName()), e); - } catch (SecurityException | NoSuchFieldException | IllegalArgumentException | - IllegalAccessException e) { - log.warn(sm.getString("webappClassLoader.clearRmiFail", - getContextName()), e); + log.info(sm.getString("webappClassLoader.clearRmiInfo", getContextName()), e); + } catch (SecurityException | NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { + log.warn(sm.getString("webappClassLoader.clearRmiFail", getContextName()), e); } catch (Exception e) { JreCompat jreCompat = JreCompat.getInstance(); if (jreCompat.isInstanceOfInaccessibleObjectException(e)) { @@ -2284,8 +2157,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader clearCache(clazz, "localDescs"); clearCache(clazz, "reflectors"); } catch (ReflectiveOperationException | SecurityException | ClassCastException e) { - log.warn(sm.getString( - "webappClassLoader.clearObjectStreamClassCachesFail", getContextName()), e); + log.warn(sm.getString("webappClassLoader.clearObjectStreamClassCachesFail", getContextName()), e); } catch (Exception e) { JreCompat jreCompat = JreCompat.getInstance(); if (jreCompat.isInstanceOfInaccessibleObjectException(e)) { @@ -2407,8 +2279,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader for (ClassFileTransformer transformer : this.transformers) { try { - byte[] transformed = transformer.transform( - this, internalName, null, null, binaryContent); + byte[] transformed = transformer.transform(this, internalName, null, null, binaryContent); if (transformed != null) { binaryContent = transformed; } @@ -2453,24 +2324,21 @@ public abstract class WebappClassLoaderBase extends URLClassLoader if (pkg.isSealed()) { sealCheck = pkg.isSealed(codeBase); } else { - sealCheck = (manifest == null) || !isPackageSealed(packageName, manifest); + sealCheck = manifest == null || !isPackageSealed(packageName, manifest); } if (!sealCheck) { - throw new SecurityException - ("Sealing violation loading " + name + " : Package " - + packageName + " is sealed."); + throw new SecurityException( + "Sealing violation loading " + name + " : Package " + packageName + " is sealed."); } } } try { - clazz = defineClass(name, binaryContent, 0, - binaryContent.length, new CodeSource(codeBase, certificates)); + clazz = defineClass(name, binaryContent, 0, binaryContent.length, + new CodeSource(codeBase, certificates)); } catch (UnsupportedClassVersionError ucve) { throw new UnsupportedClassVersionError( - ucve.getLocalizedMessage() + " " + - sm.getString("webappClassLoader.wrongVersion", - name)); + ucve.getLocalizedMessage() + " " + sm.getString("webappClassLoader.wrongVersion", name)); } entry.loadedClass = clazz; } @@ -2495,8 +2363,7 @@ public abstract class WebappClassLoaderBase extends URLClassLoader if (name.startsWith("/")) { return name; } - StringBuilder path = new StringBuilder( - 1 + name.length()); + StringBuilder path = new StringBuilder(1 + name.length()); path.append('/'); path.append(name); return path.toString(); @@ -2504,11 +2371,11 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** - * Returns true if the specified package name is sealed according to the - * given manifest. + * Returns true if the specified package name is sealed according to the given manifest. * * @param name Path name to check - * @param man Associated manifest + * @param man Associated manifest + * * @return <code>true</code> if the manifest associated says it is sealed */ protected boolean isPackageSealed(String name, Manifest man) { @@ -2530,11 +2397,11 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** - * Finds the class with the given name if it has previously been - * loaded and cached by this class loader, and return the Class object. - * If this class has not been cached, return <code>null</code>. + * Finds the class with the given name if it has previously been loaded and cached by this class loader, and return + * the Class object. If this class has not been cached, return <code>null</code>. * * @param name The binary name of the resource to return + * * @return a loaded class */ protected Class<?> findLoadedClass0(String name) { @@ -2571,9 +2438,9 @@ public abstract class WebappClassLoaderBase extends URLClassLoader /** * Filter classes. * - * @param name class name - * @param isClassName <code>true</code> if name is a class name, - * <code>false</code> if name is a resource name + * @param name class name + * @param isClassName <code>true</code> if name is a class name, <code>false</code> if name is a resource name + * * @return <code>true</code> if the class should be filtered */ protected boolean filter(String name, boolean isClassName) { @@ -2594,11 +2461,8 @@ public abstract class WebappClassLoaderBase extends URLClassLoader if (name.startsWith("servlet.jsp.jstl.", 6)) { return false; } - if (name.startsWith("annotation.", 6) || - name.startsWith("el.", 6) || - name.startsWith("servlet.", 6) || - name.startsWith("websocket.", 6) || - name.startsWith("security.auth.message.", 6)) { + if (name.startsWith("annotation.", 6) || name.startsWith("el.", 6) || name.startsWith("servlet.", 6) || + name.startsWith("websocket.", 6) || name.startsWith("security.auth.message.", 6)) { return true; } } else if (!isClassName && ch == '/') { @@ -2606,11 +2470,8 @@ public abstract class WebappClassLoaderBase extends URLClassLoader if (name.startsWith("servlet/jsp/jstl/", 6)) { return false; } - if (name.startsWith("annotation/", 6) || - name.startsWith("el/", 6) || - name.startsWith("servlet/", 6) || - name.startsWith("websocket/", 6) || - name.startsWith("security/auth/message/", 6)) { + if (name.startsWith("annotation/", 6) || name.startsWith("el/", 6) || name.startsWith("servlet/", 6) || + name.startsWith("websocket/", 6) || name.startsWith("security/auth/message/", 6)) { return true; } } @@ -2627,13 +2488,10 @@ public abstract class WebappClassLoaderBase extends URLClassLoader if (name.startsWith("tomcat.jdbc.", 11)) { return false; } - if (name.startsWith("el.", 11) || - name.startsWith("catalina.", 11) || - name.startsWith("jasper.", 11) || - name.startsWith("juli.", 11) || - name.startsWith("tomcat.", 11) || - name.startsWith("naming.", 11) || - name.startsWith("coyote.", 11)) { + if (name.startsWith("el.", 11) || name.startsWith("catalina.", 11) || + name.startsWith("jasper.", 11) || name.startsWith("juli.", 11) || + name.startsWith("tomcat.", 11) || name.startsWith("naming.", 11) || + name.startsWith("coyote.", 11)) { return true; } } @@ -2644,13 +2502,10 @@ public abstract class WebappClassLoaderBase extends URLClassLoader if (name.startsWith("tomcat/jdbc/", 11)) { return false; } - if (name.startsWith("el/", 11) || - name.startsWith("catalina/", 11) || - name.startsWith("jasper/", 11) || - name.startsWith("juli/", 11) || - name.startsWith("tomcat/", 11) || - name.startsWith("naming/", 11) || - name.startsWith("coyote/", 11)) { + if (name.startsWith("el/", 11) || name.startsWith("catalina/", 11) || + name.startsWith("jasper/", 11) || name.startsWith("juli/", 11) || + name.startsWith("tomcat/", 11) || name.startsWith("naming/", 11) || + name.startsWith("coyote/", 11)) { return true; } } diff --git a/java/org/apache/catalina/loader/WebappLoader.java b/java/org/apache/catalina/loader/WebappLoader.java index 674a52fdce..f471e3a29a 100644 --- a/java/org/apache/catalina/loader/WebappLoader.java +++ b/java/org/apache/catalina/loader/WebappLoader.java @@ -46,31 +46,25 @@ import org.apache.tomcat.util.modeler.Registry; import org.apache.tomcat.util.res.StringManager; /** - * Classloader implementation which is specialized for handling web - * applications in the most efficient way, while being Catalina aware (all - * accesses to resources are made through - * {@link org.apache.catalina.WebResourceRoot}). - * This class loader supports detection of modified - * Java classes, which can be used to implement auto-reload support. + * Classloader implementation which is specialized for handling web applications in the most efficient way, while being + * Catalina aware (all accesses to resources are made through {@link org.apache.catalina.WebResourceRoot}). This class + * loader supports detection of modified Java classes, which can be used to implement auto-reload support. * <p> - * This class loader is configured via the Resources children of its Context - * prior to calling <code>start()</code>. When a new class is required, - * these Resources will be consulted first to locate the class. If it - * is not present, the system class loader will be used instead. + * This class loader is configured via the Resources children of its Context prior to calling <code>start()</code>. When + * a new class is required, these Resources will be consulted first to locate the class. If it is not present, the + * system class loader will be used instead. * * @author Craig R. McClanahan * @author Remy Maucherat */ -public class WebappLoader extends LifecycleMBeanBase - implements Loader, PropertyChangeListener { +public class WebappLoader extends LifecycleMBeanBase implements Loader, PropertyChangeListener { private static final Log log = LogFactory.getLog(WebappLoader.class); // ----------------------------------------------------------- Constructors /** - * Construct a new WebappLoader. The parent class loader will be defined by - * {@link Context#getParentClassLoader()}. + * Construct a new WebappLoader. The parent class loader will be defined by {@link Context#getParentClassLoader()}. */ public WebappLoader() { this(null); @@ -78,14 +72,13 @@ public class WebappLoader extends LifecycleMBeanBase /** - * Construct a new WebappLoader with the specified class loader - * to be defined as the parent of the ClassLoader we ultimately create. + * Construct a new WebappLoader with the specified class loader to be defined as the parent of the ClassLoader we + * ultimately create. * * @param parent The parent class loader * - * @deprecated Use {@link Context#setParentClassLoader(ClassLoader)} to - * specify the required class loader. This method will be - * removed in Tomcat 10 onwards. + * @deprecated Use {@link Context#setParentClassLoader(ClassLoader)} to specify the required class loader. This + * method will be removed in Tomcat 10 onwards. */ @Deprecated public WebappLoader(ClassLoader parent) { @@ -109,16 +102,14 @@ public class WebappLoader extends LifecycleMBeanBase /** - * The "follow standard delegation model" flag that will be used to - * configure our ClassLoader. + * The "follow standard delegation model" flag that will be used to configure our ClassLoader. */ private boolean delegate = false; /** - * The Java class name of the ClassLoader implementation to be used. - * This class should extend WebappClassLoaderBase, otherwise, a different - * loader implementation must be used. + * The Java class name of the ClassLoader implementation to be used. This class should extend WebappClassLoaderBase, + * otherwise, a different loader implementation must be used. */ private String loaderClass = ParallelWebappClassLoader.class.getName(); @@ -200,8 +191,7 @@ public class WebappLoader extends LifecycleMBeanBase /** - * Return the "follow standard delegation model" flag used to configure - * our ClassLoader. + * Return the "follow standard delegation model" flag used to configure our ClassLoader. */ @Override public boolean getDelegate() { @@ -210,8 +200,7 @@ public class WebappLoader extends LifecycleMBeanBase /** - * Set the "follow standard delegation model" flag used to configure - * our ClassLoader. + * Set the "follow standard delegation model" flag used to configure our ClassLoader. * * @param delegate The new flag */ @@ -219,8 +208,7 @@ public class WebappLoader extends LifecycleMBeanBase public void setDelegate(boolean delegate) { boolean oldDelegate = this.delegate; this.delegate = delegate; - support.firePropertyChange("delegate", Boolean.valueOf(oldDelegate), - Boolean.valueOf(this.delegate)); + support.firePropertyChange("delegate", Boolean.valueOf(oldDelegate), Boolean.valueOf(this.delegate)); } @@ -242,9 +230,8 @@ public class WebappLoader extends LifecycleMBeanBase } /** - * Set the ClassLoader instance, without relying on reflection - * This method will also invoke {@link #setLoaderClass(String)} with - * {@code loaderInstance.getClass().getName()} as an argument + * Set the ClassLoader instance, without relying on reflection This method will also invoke + * {@link #setLoaderClass(String)} with {@code loaderInstance.getClass().getName()} as an argument * * @param loaderInstance The new ClassLoader instance to use */ @@ -273,9 +260,7 @@ public class WebappLoader extends LifecycleMBeanBase // Process this property change boolean oldReloadable = this.reloadable; this.reloadable = reloadable; - support.firePropertyChange("reloadable", - Boolean.valueOf(oldReloadable), - Boolean.valueOf(this.reloadable)); + support.firePropertyChange("reloadable", Boolean.valueOf(oldReloadable), Boolean.valueOf(this.reloadable)); } @@ -295,9 +280,8 @@ public class WebappLoader extends LifecycleMBeanBase /** - * Execute a periodic task, such as reloading, etc. This method will be - * invoked inside the classloading context of this container. Unexpected - * throwables will be caught and logged. + * Execute a periodic task, such as reloading, etc. This method will be invoked inside the classloading context of + * this container. Unexpected throwables will be caught and logged. */ @Override public void backgroundProcess() { @@ -330,8 +314,8 @@ public class WebappLoader extends LifecycleMBeanBase } public String getLoaderRepositoriesString() { - String repositories[]=getLoaderRepositories(); - StringBuilder sb=new StringBuilder(); + String repositories[] = getLoaderRepositories(); + StringBuilder sb = new StringBuilder(); for (String repository : repositories) { sb.append(repository).append(':'); } @@ -340,8 +324,7 @@ public class WebappLoader extends LifecycleMBeanBase /** - * Classpath, as set in org.apache.catalina.jsp_classpath context - * property + * Classpath, as set in org.apache.catalina.jsp_classpath context property * * @return The classpath */ @@ -351,12 +334,12 @@ public class WebappLoader extends LifecycleMBeanBase /** - * Has the internal repository associated with this Loader been modified, - * such that the loaded classes should be reloaded? + * Has the internal repository associated with this Loader been modified, such that the loaded classes should be + * reloaded? */ @Override public boolean modified() { - return classLoader != null ? classLoader.modified() : false ; + return classLoader != null ? classLoader.modified() : false; } @@ -381,11 +364,11 @@ public class WebappLoader extends LifecycleMBeanBase /** - * Start associated {@link ClassLoader} and implement the requirements - * of {@link org.apache.catalina.util.LifecycleBase#startInternal()}. + * Start associated {@link ClassLoader} and implement the requirements of + * {@link org.apache.catalina.util.LifecycleBase#startInternal()}. * - * @exception LifecycleException if this component detects a fatal error - * that prevents this component from being used + * @exception LifecycleException if this component detects a fatal error that prevents this component from being + * used */ @Override protected void startInternal() throws LifecycleException { @@ -418,11 +401,10 @@ public class WebappLoader extends LifecycleMBeanBase if (!contextName.startsWith("/")) { contextName = "/" + contextName; } - ObjectName cloname = new ObjectName(context.getDomain() + ":type=" + - classLoader.getClass().getSimpleName() + ",host=" + - context.getParent().getName() + ",context=" + contextName); - Registry.getRegistry(null, null) - .registerComponent(classLoader, cloname, null); + ObjectName cloname = + new ObjectName(context.getDomain() + ":type=" + classLoader.getClass().getSimpleName() + ",host=" + + context.getParent().getName() + ",context=" + contextName); + Registry.getRegistry(null, null).registerComponent(classLoader, cloname, null); } catch (Throwable t) { t = ExceptionUtils.unwrapInvocationTargetException(t); @@ -435,11 +417,11 @@ public class WebappLoader extends LifecycleMBeanBase /** - * Stop associated {@link ClassLoader} and implement the requirements - * of {@link org.apache.catalina.util.LifecycleBase#stopInternal()}. + * Stop associated {@link ClassLoader} and implement the requirements of + * {@link org.apache.catalina.util.LifecycleBase#stopInternal()}. * - * @exception LifecycleException if this component detects a fatal error - * that prevents this component from being used + * @exception LifecycleException if this component detects a fatal error that prevents this component from being + * used */ @Override protected void stopInternal() throws LifecycleException { @@ -468,9 +450,9 @@ public class WebappLoader extends LifecycleMBeanBase if (!contextName.startsWith("/")) { contextName = "/" + contextName; } - ObjectName cloname = new ObjectName(context.getDomain() + ":type=" + - classLoader.getClass().getSimpleName() + ",host=" + - context.getParent().getName() + ",context=" + contextName); + ObjectName cloname = + new ObjectName(context.getDomain() + ":type=" + classLoader.getClass().getSimpleName() + + ",host=" + context.getParent().getName() + ",context=" + contextName); Registry.getRegistry(null, null).unregisterComponent(cloname); } catch (Exception e) { log.warn(sm.getString("webappLoader.stopError"), e); @@ -501,11 +483,9 @@ public class WebappLoader extends LifecycleMBeanBase // Process a relevant property change if (event.getPropertyName().equals("reloadable")) { try { - setReloadable - ( ((Boolean) event.getNewValue()).booleanValue() ); + setReloadable(((Boolean) event.getNewValue()).booleanValue()); } catch (NumberFormatException e) { - log.error(sm.getString("webappLoader.reloadable", - event.getNewValue().toString())); + log.error(sm.getString("webappLoader.reloadable", event.getNewValue().toString())); } } } @@ -516,8 +496,7 @@ public class WebappLoader extends LifecycleMBeanBase /** * Create associated classLoader. */ - private WebappClassLoaderBase createClassLoader() - throws Exception { + private WebappClassLoaderBase createClassLoader() throws Exception { if (classLoader != null) { return classLoader; @@ -561,30 +540,25 @@ public class WebappLoader extends LifecycleMBeanBase ServletContext servletContext = context.getServletContext(); // Assigning permissions for the work directory - File workDir = - (File) servletContext.getAttribute(ServletContext.TEMPDIR); + File workDir = (File) servletContext.getAttribute(ServletContext.TEMPDIR); if (workDir != null) { try { String workDirPath = workDir.getCanonicalPath(); - classLoader.addPermission - (new FilePermission(workDirPath, "read,write")); - classLoader.addPermission - (new FilePermission(workDirPath + File.separator + "-", - "read,write,delete")); + classLoader.addPermission(new FilePermission(workDirPath, "read,write")); + classLoader.addPermission(new FilePermission(workDirPath + File.separator + "-", "read,write,delete")); } catch (IOException e) { // Ignore } } for (URL url : context.getResources().getBaseUrls()) { - classLoader.addPermission(url); + classLoader.addPermission(url); } } /** - * Set the appropriate context attribute for our class path. This - * is required only because Jasper depends on it. + * Set the appropriate context attribute for our class path. This is required only because Jasper depends on it. */ private void setClassPath() { @@ -649,7 +623,7 @@ public class WebappLoader extends LifecycleMBeanBase } classpath.append(repository); } - } else if (loader == ClassLoader.getSystemClassLoader()){ + } else if (loader == ClassLoader.getSystemClassLoader()) { // Java 9 onwards. The internal class loaders no longer extend // URLCLassLoader String cp = System.getProperty("java.class.path"); --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org