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
*
* <code>
* <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>
* </code>
*
@@ -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);
/**
* <code>;</code> 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<String> jarFiles = new ArrayList<String>();
+
// 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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]