Return-Path: Delivered-To: apmail-tomcat-dev-archive@www.apache.org Received: (qmail 32449 invoked from network); 20 Aug 2007 14:25:42 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 20 Aug 2007 14:25:42 -0000 Received: (qmail 6199 invoked by uid 500); 20 Aug 2007 14:25:35 -0000 Delivered-To: apmail-tomcat-dev-archive@tomcat.apache.org Received: (qmail 6162 invoked by uid 500); 20 Aug 2007 14:25:35 -0000 Mailing-List: contact dev-help@tomcat.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Tomcat Developers List" Delivered-To: mailing list dev@tomcat.apache.org Received: (qmail 6151 invoked by uid 500); 20 Aug 2007 14:25:35 -0000 Delivered-To: apmail-jakarta-tomcat-dev@jakarta.apache.org Received: (qmail 6148 invoked by uid 99); 20 Aug 2007 14:25:35 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 20 Aug 2007 07:25:35 -0700 X-ASF-Spam-Status: No, hits=-100.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 20 Aug 2007 14:26:07 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id C432B1A981A; Mon, 20 Aug 2007 07:25:14 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r567714 - /tomcat/trunk/java/org/apache/catalina/loader/VirtualWebappLoader.java Date: Mon, 20 Aug 2007 14:25:14 -0000 To: tomcat-dev@jakarta.apache.org From: fhanik@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20070820142514.C432B1A981A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: fhanik Date: Mon Aug 20 07:25:14 2007 New Revision: 567714 URL: http://svn.apache.org/viewvc?rev=567714&view=rev Log: improved upon the existing virtualwebapploader, new feature: can configure the path separator new feature: can create a local repository for runtime new feature: jar files are added as addJar to prevent locking of files Modified: tomcat/trunk/java/org/apache/catalina/loader/VirtualWebappLoader.java 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=567714&r1=567713&r2=567714&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/loader/VirtualWebappLoader.java (original) +++ tomcat/trunk/java/org/apache/catalina/loader/VirtualWebappLoader.java Mon Aug 20 07:25:14 2007 @@ -17,9 +17,14 @@ package org.apache.catalina.loader; import java.io.File; +import java.util.ArrayList; import java.util.StringTokenizer; +import java.util.jar.JarFile; import org.apache.catalina.LifecycleException; +import org.apache.catalina.startup.ExpandWar; +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; /** * Simple webapp classloader that allows a customized classpath to be added @@ -27,11 +32,22 @@ * 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 * WEB-INF/lib. + * + * The VirtualWebappLoader will add directories and regular files as org.apache.catalina.Loader.addRepository + * Jar files, or files ending with .jar, file be added as org.apache.catalina.loader.WebappClassLoader.addJar + * + * If the attribute makeLocalCopy is set to true, the VirtualWebappLoader will make a local copy of the + * virtual class path into the java.io.tmpdir directory, so that webapps can point to the same master repository, + * but be kept separate during runtime. + * + * The separator for the virtualClasspath defaulted to ; but can be configured using the separator attribute * * * <Context docBase="\webapps\mydocbase"> * <Loader className="org.apache.catalina.loader.VirtualWebappLoader" - * virtualClasspath="\dir\classes;\somedir\somejar.jar"/> + * virtualClasspath="\dir\classes:\somedir\somejar.jar" + * makeLocalCopy="true" + * separator=":"/> * </Context> * * @@ -42,17 +58,33 @@ * * * + * @author Filip Hanik * @author Fabrizio Giustina * @version $Id: $ */ public class VirtualWebappLoader extends WebappLoader { + public static final Log log = LogFactory.getLog(VirtualWebappLoader.class); /** * ; separated list of additional path elements. */ private String virtualClasspath = ""; /** + * Should we make a copy of the libraries upon startup + */ + protected boolean makeLocalCopy = false; + + /** + * The location of the libraries. + */ + protected File tempDir = null; + + /** + * The path seperator + */ + protected String separator = ";"; + /** * Construct a new WebappLoader with no defined parent class loader (so that * the actual parent will be the system class loader). */ @@ -80,11 +112,36 @@ virtualClasspath = path; } + public void setMakeLocalCopy(boolean makeLocalCopy) { + this.makeLocalCopy = makeLocalCopy; + } + + public void setSeparator(String separator) { + this.separator = separator; + } + @Override public void start() throws LifecycleException { + if (log.isInfoEnabled()) log.info("Starting VirtualWebappLoader for:"+getContainer().getName()); + ArrayList jarFiles = new ArrayList(); + // 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, ";"); + if (makeLocalCopy) { + tempDir = new File(System.getProperty("java.io.tmpdir"), "VirtualWebappLoader-"+System.identityHashCode(this)); + if (log.isDebugEnabled()) log.debug("Creating temporary directory for virtual classpath:"+tempDir.getAbsolutePath()); + if (tempDir.exists()) { + if (log.isDebugEnabled()) log.debug("Temporary directory exists, will clean out the old one."); + boolean result = false; + if (tempDir.isDirectory()) + result = ExpandWar.deleteDir(tempDir); + else + result = ExpandWar.delete(tempDir); + if (!result) throw new LifecycleException("Unable to create temp dir for virtual app loader:"+tempDir.getAbsolutePath()); + } + tempDir.mkdirs(); + } + StringTokenizer tkn = new StringTokenizer(virtualClasspath, separator); while (tkn!=null && tkn.hasMoreTokens()) { String ftkn = tkn.nextToken(); if (ftkn==null) continue; @@ -92,14 +149,60 @@ if (!file.exists()) { continue; } - if (file.isDirectory()) { - addRepository("file:/" + file.getAbsolutePath() + "/"); + File tmpFile = file; + if (makeLocalCopy) { + tmpFile = new File(tempDir, file.getName()); + if (log.isDebugEnabled()) log.debug("Creating local copy:"+tmpFile.getAbsolutePath()); + if (!ExpandWar.copy(file, tmpFile)) throw new LifecycleException("Unable to copy resources:"+file.getAbsolutePath()); + } + if (tmpFile.isDirectory()) { + if (log.isDebugEnabled()) log.debug("Adding directory to virtual repo:"+tmpFile.getAbsolutePath()); + addRepository("file:/" + tmpFile.getAbsolutePath() + "/"); + } else if (tmpFile.getAbsolutePath().endsWith(".jar")) { + //addRepository("file:/" + tmpFile.getAbsolutePath()); + jarFiles.add(tmpFile.getAbsolutePath()); } else { - addRepository("file:/" + file.getAbsolutePath()); + if (log.isDebugEnabled()) log.debug("Adding file to virtual repo:"+tmpFile.getAbsolutePath()); + addRepository("file:/" + tmpFile.getAbsolutePath()); } } - + + if (log.isDebugEnabled()) log.debug("Starting parent WebappLoader"); super.start(); + + + //add JarFiles to the classloader, we can't do that before we start + //since there is no classloader during that time + ClassLoader loader = super.getClassLoader(); + if ( loader instanceof WebappClassLoader) { + WebappClassLoader wloader = (WebappClassLoader)loader; + for (int i = 0; i < jarFiles.size(); i++) { + String filename = jarFiles.get(i); + File file = new File(filename); + try { + JarFile jfile = new JarFile(file); + if (log.isDebugEnabled()) log.debug("Adding virtual jar file to classloader:"+filename); + wloader.addJar(filename,jfile,file); + }catch ( Exception iox) { + if (log.isDebugEnabled()) log.debug("",iox); + } + } + } + } + + @Override + public void stop() throws LifecycleException { + super.stop(); + boolean result = true; + if ( tempDir!=null ) result = ExpandWar.deleteDir(tempDir); + if (!result) log.info("Unable to delete temporary directory:"+tempDir.getAbsolutePath()); } + public boolean getMakeLocalCopy() { + return makeLocalCopy; + } + + public String getSeparator() { + return separator; + } } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org For additional commands, e-mail: dev-help@tomcat.apache.org