Author: kkolinko Date: Mon Jun 28 15:59:12 2010 New Revision: 958615 URL: http://svn.apache.org/viewvc?rev=958615&view=rev Log: Implement support for using *.jar pattern in VirtualWebappLoader to specify all JAR files in a certain directory.
This is inspired by Bootstrap.createClassLoader(..) and ClassLoaderFactory.createClassLoader(..). There is a small difference with regards to ClassLoaderFactory.createClassLoader(..) implementation: 1. I removed the file.canRead() checks as I think that they are not necessary here. I am checking existence and type only. 2. Note that isFile()/isDirectory() are documented to return false if the path does not exist, so using a separate exists() call there is not necessary. Also three other changes: 1. Added trim() to the tokens. 2. Implemented debug logging. 3. Removed "not for production" warning from the JavaDoc. An update for the documentation (/config/loader.html) should follow later. Modified: tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties tomcat/trunk/java/org/apache/catalina/loader/VirtualWebappLoader.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties?rev=958615&r1=958614&r2=958615&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties Mon Jun 28 15:59:12 2010 @@ -28,6 +28,12 @@ standardLoader.reloading=Reloading check standardLoader.removeRepository=Removing repository {0} standardLoader.starting=Starting this Loader standardLoader.stopping=Stopping this Loader +virtualWebappLoader.token=Processing token [{0}] +virtualWebappLoader.token.file=Adding location: [{0}] +virtualWebappLoader.token.glob.dir=Listing files in a directory: [{0}] +virtualWebappLoader.token.notDirectory=Path is skipped, because it does not exist or is not a directory: [{0}] +virtualWebappLoader.token.notExists=Path is skipped, because it does not exist: [{0}] +virtualWebappLoader.token.notFile=Path is skipped, because it does not exist or is not a file: [{0}] webappClassLoader.illegalJarPath=Illegal JAR entry detected with name {0} webappClassLoader.jdbcRemoveFailed=JDBC driver de-registration failed for web application [{0}] webappClassLoader.jdbcRemoveStreamError=Exception closing input stream during JDBC driver de-registration for web application [{0}] Modified: tomcat/trunk/java/org/apache/catalina/loader/VirtualWebappLoader.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/loader/VirtualWebappLoader.java?rev=958615&r1=958614&r2=958615&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/loader/VirtualWebappLoader.java (original) +++ tomcat/trunk/java/org/apache/catalina/loader/VirtualWebappLoader.java Mon Jun 28 15:59:12 2010 @@ -17,13 +17,17 @@ package org.apache.catalina.loader; import java.io.File; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.Locale; +import java.util.Set; import java.util.StringTokenizer; import org.apache.catalina.LifecycleException; import org.apache.catalina.util.LifecycleBase; /** - * Simple webapp classloader that allows a customized classpath to be added + * A WebappLoader that allows a customized classpath to be added * through configuration in context xml. Any additional classpath entry will be * added to the default webapp classpath, making easy to emulate a standard * webapp without the need for assembly all the webapp dependencies as jars in @@ -32,15 +36,14 @@ import org.apache.catalina.util.Lifecycl * <pre> * <Context docBase="\webapps\mydocbase"> * <Loader className="org.apache.catalina.loader.VirtualWebappLoader" - * virtualClasspath="\dir\classes;\somedir\somejar.jar"/> + * virtualClasspath="/dir/classes;/somedir/somejar.jar;/somedir/*.jar"/> * </Context> * </pre> * - * - * <strong>This is not meant to be used for production. - * Its meant to ease development with IDE's without the - * need for fully republishing jars in WEB-INF/lib</strong> - * + * <p>The <code>*.jar</code> suffix can be used to include all JAR files in a + * certain directory. If a file or a directory does not exist, it will be + * skipped. + * </p> * * * @author Fabrizio Giustina @@ -48,6 +51,9 @@ import org.apache.catalina.util.Lifecycl */ public class VirtualWebappLoader extends WebappLoader { + private static final org.apache.juli.logging.Log log= + org.apache.juli.logging.LogFactory.getLog( VirtualWebappLoader.class ); + /** * <code>;</code> separated list of additional path elements. */ @@ -108,12 +114,75 @@ public class VirtualWebappLoader extends // just add any jar/directory set in virtual classpath to the // repositories list before calling start on the standard WebappLoader StringTokenizer tkn = new StringTokenizer(virtualClasspath, ";"); + Set<String> set = new LinkedHashSet<String>(); while (tkn.hasMoreTokens()) { - File file = new File(tkn.nextToken()); - if (!file.exists()) { - continue; + String token = tkn.nextToken().trim(); + + if (log.isDebugEnabled()) + log.debug(sm.getString("virtualWebappLoader.token", token)); + + if (token.endsWith("*.jar")) { + // glob + token = token.substring(0, token.length() - "*.jar".length()); + + File directory = new File(token); + if (!directory.isDirectory()) { + if (log.isDebugEnabled()) { + log.debug(sm.getString( + "virtualWebappLoader.token.notDirectory", + directory.getAbsolutePath())); + } + continue; + } + if (log.isDebugEnabled()) { + log.debug(sm.getString( + "virtualWebappLoader.token.glob.dir", + directory.getAbsolutePath())); + } + String filenames[] = directory.list(); + Arrays.sort(filenames); + for (int j = 0; j < filenames.length; j++) { + String filename = filenames[j].toLowerCase(Locale.ENGLISH); + if (!filename.endsWith(".jar")) + continue; + File file = new File(directory, filenames[j]); + if (!file.isFile()) { + if (log.isDebugEnabled()) { + log.debug(sm.getString( + "virtualWebappLoader.token.notFile", + file.getAbsolutePath())); + } + continue; + } + if (log.isDebugEnabled()) { + log.debug(sm.getString( + "virtualWebappLoader.token.file", + file.getAbsolutePath())); + } + set.add(file.toURI().toString()); + } + } else { + // single file or directory + File file = new File(token); + if (!file.exists()) { + if (log.isDebugEnabled()) { + log.debug(sm.getString( + "virtualWebappLoader.token.notExists", + file.getAbsolutePath())); + } + continue; + } + if (log.isDebugEnabled()) { + log.debug(sm.getString( + "virtualWebappLoader.token.file", + file.getAbsolutePath())); + } + set.add(file.toURI().toString()); } - addRepository(file.toURI().toString()); + } + + for (String repository: set) { + addRepository(repository); } super.startInternal(); Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=958615&r1=958614&r2=958615&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Mon Jun 28 15:59:12 2010 @@ -71,6 +71,10 @@ request processing threads and threads started by the application. (markt) </fix> + <add> + Add support for <code>*.jar</code> pattern in VirtualWebappLoader. + (kkolinko) + </add> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org