Author: rjung Date: Mon Jun 28 11:03:12 2010 New Revision: 958543 URL: http://svn.apache.org/viewvc?rev=958543&view=rev Log: Add property "searchExternalFirst" to WebappLoader.
If set, the external repositories will be searched before the WEB-INF ones. Default (false) is unchanged behaviour. Also expose the new property via JMX and document it. Backport from trunk of r936823 and r956252. Modified: tomcat/tc6.0.x/trunk/STATUS.txt tomcat/tc6.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java tomcat/tc6.0.x/trunk/java/org/apache/catalina/loader/WebappLoader.java tomcat/tc6.0.x/trunk/java/org/apache/catalina/loader/mbeans-descriptors.xml tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml tomcat/tc6.0.x/trunk/webapps/docs/config/loader.xml Modified: tomcat/tc6.0.x/trunk/STATUS.txt URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS.txt?rev=958543&r1=958542&r2=958543&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/STATUS.txt (original) +++ tomcat/tc6.0.x/trunk/STATUS.txt Mon Jun 28 11:03:12 2010 @@ -81,17 +81,6 @@ PATCHES PROPOSED TO BACKPORT: * Backport a couple of loader fixes and enhancements: - Add property "searchExternalFirst" to WebappLoader: - If set, the external repositories will be searched before - the WEB-INF ones. Default (false) is unchanged behaviour. - Also expose the new property via JMX and document it. - http://svn.apache.org/viewvc?view=revision&revision=936823 - http://people.apache.org/~rjung/patches/2010-05-14-loader-backport-r936823.patch - +1: rjung - +1: markt if r956252 is also applied - +1: kkolinko if r956252 is also applied - -1: - Expose the new WebappLoader flag in the VirtualWebappLoader, but allow alternative name searchVirtualFirst to make it consistent with the "virtual" terminology. Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java?rev=958543&r1=958542&r2=958543&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java Mon Jun 28 11:03:12 2010 @@ -427,6 +427,11 @@ public class WebappClassLoader protected boolean hasExternalRepositories = false; /** + * Search external repositories first + */ + protected boolean searchExternalFirst = false; + + /** * need conversion for properties files */ protected boolean needConvert = false; @@ -556,7 +561,21 @@ public class WebappClassLoader this.antiJARLocking = antiJARLocking; } - + /** + * @return Returns the searchExternalFirst. + */ + public boolean getSearchExternalFirst() { + return searchExternalFirst; + } + + /** + * @param searchExternalFirst Whether external repositories should be searched first + */ + public void setSearchExternalFirst(boolean searchExternalFirst) { + this.searchExternalFirst = searchExternalFirst; + } + + /** * If there is a Java SecurityManager create a read FilePermission * or JndiPermission for the file directory path. @@ -1085,22 +1104,39 @@ public class WebappClassLoader try { if (log.isTraceEnabled()) log.trace(" findClassInternal(" + name + ")"); - try { - clazz = findClassInternal(name); - } catch(ClassNotFoundException cnfe) { - if (!hasExternalRepositories) { - throw cnfe; - } - } catch(AccessControlException ace) { - log.warn("WebappClassLoader.findClassInternal(" + name - + ") security exception: " + ace.getMessage(), ace); - throw new ClassNotFoundException(name, ace); - } catch (RuntimeException e) { - if (log.isTraceEnabled()) - log.trace(" -->RuntimeException Rethrown", e); - throw e; + if (hasExternalRepositories && searchExternalFirst) { + try { + clazz = super.findClass(name); + } catch(ClassNotFoundException cnfe) { + // Ignore - will search internal repositories next + } catch(AccessControlException ace) { + log.warn("WebappClassLoader.findClassInternal(" + name + + ") security exception: " + ace.getMessage(), ace); + throw new ClassNotFoundException(name, ace); + } catch (RuntimeException e) { + if (log.isTraceEnabled()) + log.trace(" -->RuntimeException Rethrown", e); + throw e; + } + } + if ((clazz == null)) { + try { + clazz = findClassInternal(name); + } catch(ClassNotFoundException cnfe) { + if (!hasExternalRepositories || searchExternalFirst) { + throw cnfe; + } + } catch(AccessControlException ace) { + log.warn("WebappClassLoader.findClassInternal(" + name + + ") security exception: " + ace.getMessage(), ace); + throw new ClassNotFoundException(name, ace); + } catch (RuntimeException e) { + if (log.isTraceEnabled()) + log.trace(" -->RuntimeException Rethrown", e); + throw e; + } } - if ((clazz == null) && hasExternalRepositories) { + if ((clazz == null) && hasExternalRepositories && !searchExternalFirst) { try { clazz = super.findClass(name); } catch(AccessControlException ace) { @@ -1157,21 +1193,26 @@ public class WebappClassLoader URL url = null; - ResourceEntry entry = (ResourceEntry) resourceEntries.get(name); - if (entry == null) { - if (securityManager != null) { - PrivilegedAction<ResourceEntry> dp = - new PrivilegedFindResourceByName(name, name); - entry = AccessController.doPrivileged(dp); - } else { - entry = findResourceInternal(name, name); + if (hasExternalRepositories && searchExternalFirst) + url = super.findResource(name); + + if (url == null) { + ResourceEntry entry = (ResourceEntry) resourceEntries.get(name); + if (entry == null) { + if (securityManager != null) { + PrivilegedAction<ResourceEntry> dp = + new PrivilegedFindResourceByName(name, name); + entry = AccessController.doPrivileged(dp); + } else { + entry = findResourceInternal(name, name); + } + } + if (entry != null) { + url = entry.source; } - } - if (entry != null) { - url = entry.source; } - if ((url == null) && hasExternalRepositories) + if ((url == null) && hasExternalRepositories && !searchExternalFirst) url = super.findResource(name); if (log.isDebugEnabled()) { @@ -1206,6 +1247,16 @@ public class WebappClassLoader int i; + // Adding the results of a call to the superclass + if (hasExternalRepositories && searchExternalFirst) { + + Enumeration<URL> otherResourcePaths = super.findResources(name); + + while (otherResourcePaths.hasMoreElements()) { + result.addElement(otherResourcePaths.nextElement()); + } + + } // Looking at the repositories for (i = 0; i < repositoriesLength; i++) { try { @@ -1241,7 +1292,7 @@ public class WebappClassLoader } // Adding the results of a call to the superclass - if (hasExternalRepositories) { + if (hasExternalRepositories && !searchExternalFirst) { Enumeration otherResourcePaths = super.findResources(name); @@ -3181,4 +3232,3 @@ public class WebappClassLoader } - Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/loader/WebappLoader.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/loader/WebappLoader.java?rev=958543&r1=958542&r2=958543&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/loader/WebappLoader.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/loader/WebappLoader.java Mon Jun 28 11:03:12 2010 @@ -209,6 +209,12 @@ public class WebappLoader private ArrayList loaderRepositories = null; + /** + * Whether we should search the external repositories first + */ + private boolean searchExternalFirst = false; + + // ------------------------------------------------------------- Properties @@ -344,6 +350,23 @@ public class WebappLoader } + /** + * @return Returns searchExternalFirst. + */ + public boolean getSearchExternalFirst() { + return searchExternalFirst; + } + + /** + * @param searchExternalFirst Whether external repositories should be searched first + */ + public void setSearchExternalFirst(boolean searchExternalFirst) { + this.searchExternalFirst = searchExternalFirst; + if (classLoader != null) { + classLoader.setSearchExternalFirst(searchExternalFirst); + } + } + // --------------------------------------------------------- Public Methods @@ -638,6 +661,7 @@ public class WebappLoader classLoader = createClassLoader(); classLoader.setResources(container.getResources()); classLoader.setDelegate(this.delegate); + classLoader.setSearchExternalFirst(searchExternalFirst); if (container instanceof StandardContext) { classLoader.setAntiJARLocking( ((StandardContext) container).getAntiJARLocking()); Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/loader/mbeans-descriptors.xml URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/loader/mbeans-descriptors.xml?rev=958543&r1=958542&r2=958543&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/loader/mbeans-descriptors.xml (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/loader/mbeans-descriptors.xml Mon Jun 28 11:03:12 2010 @@ -36,6 +36,10 @@ description="The reloadable flag for this Loader" type="boolean"/> + <attribute name="searchExternalFirst" + description="The searchExternalFirst flag for this Loader" + type="boolean"/> + <attribute name="repositories" description="Extra repositories managed by this loader" type="[Ljava.lang.String;"/> @@ -132,6 +136,10 @@ description="The antiJARLocking flag for this Loader" type="boolean"/> + <attribute name="searchExternalFirst" + description="The searchExternalFirst flag for this Loader" + type="boolean"/> + <attribute name="URLs" description="The URLs of this loader" type="[Ljava.net.URL;"/> Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?rev=958543&r1=958542&r2=958543&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Mon Jun 28 11:03:12 2010 @@ -56,6 +56,11 @@ <bug>49443</bug>: Use remoteIpHeader rather than remoteIPHeader consistently. (markt) </fix> + <add> + Add property <code>searchExternalFirst</code> to WebappLoader. + If set, the external repositories will be searched before + the WEB-INF ones. (rjung) + </add> </changelog> </subsection> <subsection name="Cluster"> Modified: tomcat/tc6.0.x/trunk/webapps/docs/config/loader.xml URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/config/loader.xml?rev=958543&r1=958542&r2=958543&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/webapps/docs/config/loader.xml (original) +++ tomcat/tc6.0.x/trunk/webapps/docs/config/loader.xml Mon Jun 28 11:03:12 2010 @@ -130,6 +130,12 @@ <code>org.apache.catalina.loader.WebappClassLoader</code>.</p> </attribute> + <attribute name="searchExternalFirst" required="false"> + <p>Set to <code>true</code> if you want repositories outside + of <code>WEB-INF/classes</code> and <code>WEB-INF/lib</code> to + be searched first. Default value is <code>false</code>.</p> + </attribute> + </attributes> </subsection> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org