You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by sy...@apache.org on 2003/06/03 15:25:43 UTC
cvs commit: cocoon-2.1/src/java/org/apache/cocoon/servlet BootstrapServlet.java CocoonServlet.java ParanoidClassLoader.java ParanoidCocoonServlet.java
sylvain 2003/06/03 06:25:43
Modified: src/java/org/apache/cocoon/servlet BootstrapServlet.java
CocoonServlet.java ParanoidClassLoader.java
ParanoidCocoonServlet.java
Log:
ParanoidCocoonServlet is now really paranoid
Revision Changes Path
1.2 +53 -139 cocoon-2.1/src/java/org/apache/cocoon/servlet/BootstrapServlet.java
Index: BootstrapServlet.java
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/java/org/apache/cocoon/servlet/BootstrapServlet.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- BootstrapServlet.java 9 Mar 2003 00:09:37 -0000 1.1
+++ BootstrapServlet.java 3 Jun 2003 13:25:42 -0000 1.2
@@ -50,19 +50,19 @@
*/
package org.apache.cocoon.servlet;
-import javax.servlet.*;
-import javax.servlet.http.HttpServlet;
-
import java.io.File;
-import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
-import java.util.ArrayList;
import java.util.Enumeration;
-import java.util.List;
import java.util.Set;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
/**
* A bootstrap servlet to allow Cocoon to run in servlet engines that aren't fully
* compliant with the servlet 2.2 spec.
@@ -81,141 +81,55 @@
* @version CVS $Id$
*/
-public class BootstrapServlet extends HttpServlet {
-
- /**
- * The name of the actual servlet class.
- */
- public static final String SERVLET_CLASS = "org.apache.cocoon.servlet.CocoonServlet";
+public class BootstrapServlet extends ParanoidCocoonServlet {
- protected Servlet servlet;
+ private File contextDir;
- protected ClassLoader classloader;
-
- protected ServletContext context;
-
- public void init(ServletConfig config) throws ServletException {
- this.context = config.getServletContext();
-
- this.context.log("getRealPath(\"/\") = " + context.getRealPath("/"));
-
- String contextDirParam = config.getInitParameter("context-directory");
- if (contextDirParam == null) {
- // Check old form, not consistent with other parameter names
- contextDirParam = config.getInitParameter("context-dir");
- if (contextDirParam == null) {
- String msg = "The 'context-directory' parameter must be set to the root of the servlet context";
- this.context.log(msg);
- throw new ServletException(msg);
- } else {
- this.context.log("Parameter 'context-dir' is deprecated - use 'context-directory'");
- }
- }
-
- // Ensure context dir doesn't end with a "/" (servlet spec says that paths for
- // getResource() should start by a "/")
- if (contextDirParam.endsWith("/")) {
- contextDirParam = contextDirParam.substring(0, contextDirParam.length() - 1);
- }
-
- // Ensure context dir exists and is a directory
- File contextDir = new File(contextDirParam);
- if (!contextDir.exists()) {
- String msg = "Context dir '" + contextDir + "' doesn't exist";
- this.context.log(msg);
- throw new ServletException(msg);
- }
+ protected File getContextDir() throws ServletException {
+
+ ServletContext context = getServletContext();
+ ServletConfig config = getServletConfig();
+
+ log("getRealPath(\"/\") = " + context.getRealPath("/"));
+
+ String contextDirParam = config.getInitParameter("context-directory");
+
+ if (contextDirParam == null) {
+ throw new ServletException("The 'context-directory' parameter must be set to the root of the servlet context");
+ }
+
+ // Ensure context dir doesn't end with a "/" (servlet spec says that paths for
+ // getResource() should start by a "/")
+ if (contextDirParam.endsWith("/")) {
+ contextDirParam = contextDirParam.substring(0, contextDirParam.length() - 1);
+ }
+
+ // Ensure context dir exists and is a directory
+ this.contextDir = new File(contextDirParam);
+ if (!this.contextDir.exists()) {
+ String msg = "Context dir '" + this.contextDir + "' doesn't exist";
+ log(msg);
+ throw new ServletException(msg);
+ }
+
+ if (!this.contextDir.isDirectory()) {
+ String msg = "Context dir '" + this.contextDir + "' should be a directory";
+ log(msg);
+ throw new ServletException(msg);
+ }
+
+ context.log("Context dir set to " + this.contextDir);
+
+ return this.contextDir;
+ }
- if (!contextDir.isDirectory()) {
- String msg = "Context dir '" + contextDir + "' should be a directory";
- this.context.log(msg);
- throw new ServletException(msg);
- }
-
- context.log("Context dir set to " + contextDir);
- this.classloader = getClassLoader(contextDirParam);
-
- try {
- Class servletClass = this.classloader.loadClass(SERVLET_CLASS);
-
- this.servlet = (Servlet)servletClass.newInstance();
- } catch(Exception e) {
- context.log("Cannot load servlet", e);
- throw new ServletException(e);
- }
-
- // Always set the context classloader. JAXP uses it to find a ParserFactory,
- // and thus fails if it's not set to the webapp classloader.
- Thread.currentThread().setContextClassLoader(this.classloader);
-
- ServletContext newContext = new ContextWrapper(context, contextDirParam);
- ServletConfig newConfig = new ConfigWrapper(config, newContext);
+ protected void initServlet(Servlet servlet) throws ServletException {
- super.init(newConfig);
+ ServletContext newContext = new ContextWrapper(getServletContext(), this.contextDir);
+ ServletConfig newConfig = new ConfigWrapper(getServletConfig(), newContext);
- // Inlitialize the actual servlet
- this.servlet.init(newConfig);
-
- }
-
- /**
- * Get the classloader that will be used to create the actual servlet.
- */
- protected ClassLoader getClassLoader(String contextDirParam) throws ServletException {
- List urlList = new ArrayList();
-
- try {
- File classDir = new File(contextDirParam + "/WEB-INF/classes");
- if (classDir.exists()) {
- if (!classDir.isDirectory()) {
- String msg = classDir + " exists but is not a directory";
- this.context.log(msg);
- throw new ServletException(msg);
- }
-
- URL classURL = classDir.toURL();
- context.log("Adding class directory " + classURL);
- urlList.add(classURL);
-
- }
-
- File libDir = new File(contextDirParam + "/WEB-INF/lib");
- File[] libraries = libDir.listFiles();
-
- for (int i = 0; i < libraries.length; i++) {
- URL lib = libraries[i].toURL();
- context.log("Adding class library " + lib);
- urlList.add(lib);
- }
- } catch (MalformedURLException mue) {
- context.log("Malformed url", mue);
- throw new ServletException(mue);
- }
-
- URL[] urls = (URL[])urlList.toArray(new URL[urlList.size()]);
-
- return ParanoidClassLoader.newInstance(urls, this.getClass().getClassLoader());
- }
-
- /**
- * Service the request by delegating the call to the real servlet
- */
- public void service(ServletRequest request, ServletResponse response)
- throws ServletException, IOException {
-
- Thread.currentThread().setContextClassLoader(this.classloader);
- this.servlet.service(request, response);
- }
-
- /**
- * Destroy the actual servlet
- */
- public void destroy() {
-
- super.destroy();
- Thread.currentThread().setContextClassLoader(this.classloader);
- this.servlet.destroy();
+ servlet.init(newConfig);
}
//-------------------------------------------------------------------------
@@ -260,13 +174,13 @@
*/
public static class ContextWrapper implements ServletContext {
ServletContext context;
- String contextRoot;
+ File contextRoot;
/**
* Builds a wrapper around an existing context, and handle all
* resource resolution relatively to <code>contextRoot</code>
*/
- public ContextWrapper(ServletContext context, String contextRoot) {
+ public ContextWrapper(ServletContext context, File contextRoot) {
this.context = context;
this.contextRoot = contextRoot;
}
@@ -293,7 +207,7 @@
* returned.
*/
public URL getResource(String path) throws MalformedURLException {
- File file = new File(this.contextRoot + path);
+ File file = new File(this.contextRoot, path);
if (file.exists()) {
URL result = file.toURL();
//this.context.log("getResource(" + path + ") = " + result);
1.8 +83 -100 cocoon-2.1/src/java/org/apache/cocoon/servlet/CocoonServlet.java
Index: CocoonServlet.java
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/java/org/apache/cocoon/servlet/CocoonServlet.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- CocoonServlet.java 20 May 2003 12:38:27 -0000 1.7
+++ CocoonServlet.java 3 Jun 2003 13:25:42 -0000 1.8
@@ -269,9 +269,12 @@
super.init(conf);
- final String initClassLoaderParam = conf.getInitParameter("init-classloader");
- this.initClassLoader = "true".equalsIgnoreCase(initClassLoaderParam) ||
- "yes".equalsIgnoreCase(initClassLoaderParam);
+ // Check the init-classloader parameter only if it's not already true.
+ // This is useful for subclasses of this servlet that override the value
+ // initially set by this class (i.e. false).
+ if (!this.initClassLoader) {
+ this.initClassLoader = getInitParameterAsBoolean("init-classloader", false);
+ }
if (this.initClassLoader) {
// Force context classloader so that JAXP can work correctly
@@ -298,8 +301,8 @@
// first init the work-directory for the logger.
// this is required if we are running inside a war file!
- final String workDirParam = conf.getInitParameter("work-directory");
- if ((workDirParam != null) && (!workDirParam.trim().equals(""))) {
+ final String workDirParam = getInitParameter("work-directory");
+ if (workDirParam != null) {
if (this.servletContextPath == null) {
// No context path : consider work-directory as absolute
this.workDir = new File(workDirParam);
@@ -361,17 +364,12 @@
log.debug("URL for Root: " + this.servletContextURL);
}
- this.forceLoadParameter = conf.getInitParameter("load-class");
- if (conf.getInitParameter("load-class") == null) {
- if (log.isDebugEnabled()) {
- log.debug("load-class was not set - defaulting to false?");
- }
- }
+ this.forceLoadParameter = getInitParameter("load-class", null);
- this.forceSystemProperty = conf.getInitParameter("force-property");
+ this.forceSystemProperty = getInitParameter("force-property", null);
// add work directory
- if ((workDirParam != null) && (!workDirParam.trim().equals(""))) {
+ if (workDirParam != null) {
if (log.isDebugEnabled()) {
log.debug("Using work-directory " + this.workDir);
}
@@ -383,7 +381,7 @@
this.appContext.put(Constants.CONTEXT_WORK_DIR, workDir);
final String uploadDirParam = conf.getInitParameter("upload-directory");
- if ((uploadDirParam != null) && (!uploadDirParam.trim().equals(""))) {
+ if (uploadDirParam != null) {
if (this.servletContextPath == null) {
this.uploadDir = new File(uploadDirParam);
} else {
@@ -409,33 +407,12 @@
this.uploadDir.mkdirs();
this.appContext.put(Constants.CONTEXT_UPLOAD_DIR, this.uploadDir);
- value = conf.getInitParameter("enable-uploads");
- if (value != null) {
- this.enableUploads = ("yes".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value));
- } else {
- this.enableUploads = ENABLE_UPLOADS;
- if (log.isDebugEnabled()) {
- log.debug("enable-uploads was not set - defaulting to " + this.enableUploads);
- }
- }
+ this.enableUploads = getInitParameterAsBoolean("enable-uploads", ENABLE_UPLOADS);
- value = conf.getInitParameter("autosave-uploads");
- if (value != null) {
- this.autoSaveUploads = ("yes".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value));
- } else {
- this.autoSaveUploads = SAVE_UPLOADS_TO_DISK;
- if (log.isDebugEnabled()) {
- log.debug("autosave-uploads was not set - defaulting to " + this.autoSaveUploads);
- }
- }
+ this.autoSaveUploads = getInitParameterAsBoolean("autosave-uploads", SAVE_UPLOADS_TO_DISK);
- String overwriteParam = conf.getInitParameter("overwrite-uploads");
+ String overwriteParam = getInitParameter("overwrite-uploads", "rename");
// accepted values are deny|allow|rename - rename is default.
- if (overwriteParam == null) {
- if (log.isDebugEnabled()) {
- log.debug("overwrite-uploads was not set - defaulting to rename");
- }
- }
if ("deny".equalsIgnoreCase(overwriteParam)) {
this.allowOverwrite = false;
this.silentlyRename = false;
@@ -448,14 +425,10 @@
this.silentlyRename = true;
}
- this.maxUploadSize = MAX_UPLOAD_SIZE;
- String maxSizeParam = conf.getInitParameter("upload-max-size");
- if ((maxSizeParam != null) && (!maxSizeParam.trim().equals(""))) {
- this.maxUploadSize = Integer.parseInt(maxSizeParam);
- }
+ this.maxUploadSize = getInitParameterAsInteger("upload-max-size", MAX_UPLOAD_SIZE);
String cacheDirParam = conf.getInitParameter("cache-directory");
- if ((cacheDirParam != null) && (!cacheDirParam.trim().equals(""))) {
+ if (cacheDirParam != null) {
if (this.servletContextPath == null) {
this.cacheDir = new File(cacheDirParam);
} else {
@@ -490,15 +463,7 @@
}
// get allow reload parameter, default is true
- value = conf.getInitParameter("allow-reload");
- if (value != null) {
- this.allowReload = value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("true");
- } else {
- this.allowReload = ALLOW_RELOAD;
- if (log.isDebugEnabled()) {
- log.debug("allow-reload was not set - defaulting to " + ALLOW_RELOAD);
- }
- }
+ this.allowReload = getInitParameterAsBoolean("allow-reload", ALLOW_RELOAD);
value = conf.getInitParameter("show-time");
this.showTime = "yes".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value)
@@ -509,12 +474,8 @@
}
}
- parentComponentManagerClass = conf.getInitParameter("parent-component-manager");
- if (parentComponentManagerClass == null) {
- if (log.isDebugEnabled()) {
- log.debug("parent-component-manager was not set - defaulting to null.");
- }
- } else {
+ parentComponentManagerClass = getInitParameter("parent-component-manager", null);
+ if (parentComponentManagerClass != null) {
int dividerPos = parentComponentManagerClass.indexOf('/');
if (dividerPos != -1) {
parentComponentManagerInitParam = parentComponentManagerClass.substring(dividerPos + 1);
@@ -522,38 +483,12 @@
}
}
- this.containerEncoding = conf.getInitParameter("container-encoding");
- if (containerEncoding == null) {
- this.containerEncoding = "ISO-8859-1";
- if (log.isDebugEnabled()) {
- log.debug("container-encoding was not set - defaulting to ISO-8859-1.");
- }
- }
-
- this.defaultFormEncoding = conf.getInitParameter("form-encoding");
- if (defaultFormEncoding == null) {
- this.defaultFormEncoding = "ISO-8859-1";
- if (log.isDebugEnabled()) {
- log.debug("form-encoding was not set - defaulting to ISO-8859-1.");
- }
- }
+ this.containerEncoding = getInitParameter("container-encoding", "ISO-8859-1");
+ this.defaultFormEncoding = getInitParameter("form-encoding","ISO-8859-1");
- value = conf.getInitParameter("manage-exceptions");
- this.manageExceptions = (value == null || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("true"));
- if (value == null) {
- if (log.isDebugEnabled()) {
- log.debug("Parameter manageExceptions was not set - defaulting to true.");
- }
- }
+ this.manageExceptions = getInitParameterAsBoolean("manage-exceptions", true);
- value = conf.getInitParameter("enable-instrumentation");
- this.enableInstrumentation =
- "yes".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value);
- if (value == null) {
- if (log.isDebugEnabled()) {
- log.debug("enable-instrumentation was not set - defaulting to false.");
- }
- }
+ this.enableInstrumentation = getInitParameterAsBoolean("enable-instrumentation", false);
this.requestFactory = new RequestFactory(this.autoSaveUploads,
this.uploadDir,
@@ -790,7 +725,7 @@
protected String getExtraClassPath()
throws ServletException {
String extraClassPath = this.getInitParameter("extra-classpath");
- if ((extraClassPath != null) && !extraClassPath.trim().equals("")) {
+ if (extraClassPath != null) {
StringBuffer sb = new StringBuffer();
StringTokenizer st = new StringTokenizer(extraClassPath, System.getProperty("path.separator"), false);
int i = 0;
@@ -849,14 +784,11 @@
* file.
*/
private void initLogger() {
- String logLevel = getInitParameter("log-level");
- if (logLevel == null) {
- logLevel = "INFO";
- }
+ String logLevel = getInitParameter("log-level", "INFO");
final String accesslogger = getInitParameter("servlet-logger");
- final Priority logPriority = Priority.getPriorityForName(logLevel.trim());
+ final Priority logPriority = Priority.getPriorityForName(logLevel);
final ServletOutputLogTarget servTarget = new ServletOutputLogTarget(this.servletContext);
@@ -888,10 +820,7 @@
this.logKitManager = logKitManager;
//Configure the logkit management
- String logkitConfig = getInitParameter("logkit-config");
- if (logkitConfig == null) {
- logkitConfig = "/WEB-INF/logkit.xconf";
- }
+ String logkitConfig = getInitParameter("logkit-config", "/WEB-INF/logkit.xconf");
InputStream is = this.servletContext.getResourceAsStream(logkitConfig);
if (is == null) is = new FileInputStream(logkitConfig);
@@ -1511,5 +1440,59 @@
this.cocoon.dispose();
this.cocoon = null;
}
+ }
+
+ /**
+ * Get an initialisation parameter. The value is trimmed, and null is returned if the trimmed value
+ * is empty.
+ */
+ public String getInitParameter(String name) {
+ String result = super.getInitParameter(name);
+ if (result != null) {
+ result = result.trim();
+ if (result.length() == 0) {
+ result = null;
+ }
+ }
+
+ return result;
+ }
+
+ /** Convenience method to access servlet parameters */
+ protected String getInitParameter(String name, String defaultValue) {
+ String result = getInitParameter(name);
+ if (result == null) {
+ if (log != null && log.isDebugEnabled()) {
+ log.debug(name + " was not set - defaulting to '" + defaultValue + "'");
+ }
+ return defaultValue;
+ } else {
+ return result;
+ }
+ }
+
+ /** Convenience method to access boolean servlet parameters */
+ protected boolean getInitParameterAsBoolean(String name, boolean defaultValue) {
+ String value = getInitParameter(name);
+ if (value == null) {
+ if (log != null && log.isDebugEnabled()) {
+ log.debug(name + " was not set - defaulting to '" + defaultValue + "'");
+ }
+ return defaultValue;
+ } else {
+ return value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes");
+ }
+ }
+
+ protected int getInitParameterAsInteger(String name, int defaultValue) {
+ String value = getInitParameter(name);
+ if (value == null) {
+ if (log != null && log.isDebugEnabled()) {
+ log.debug(name + " was not set - defaulting to '" + defaultValue + "'");
+ }
+ return defaultValue;
+ } else {
+ return Integer.parseInt(value);
+ }
}
}
1.2 +12 -3 cocoon-2.1/src/java/org/apache/cocoon/servlet/ParanoidClassLoader.java
Index: ParanoidClassLoader.java
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/java/org/apache/cocoon/servlet/ParanoidClassLoader.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ParanoidClassLoader.java 9 Mar 2003 00:09:37 -0000 1.1
+++ ParanoidClassLoader.java 3 Jun 2003 13:25:42 -0000 1.2
@@ -64,7 +64,7 @@
* classes. It checks this classloader before it checks its parent.
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
- * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
+ * @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
* @version CVS $Id$
*/
@@ -85,7 +85,7 @@
* Alternate constructor to define a parent.
*/
public ParanoidClassLoader(final ClassLoader parent) {
- this(null, parent, null);
+ this(new URL[0], parent, null);
}
/**
@@ -151,6 +151,7 @@
try {
clazz = findClass(name);
+ //System.err.println("Paranoid load : " + name);
} catch (ClassNotFoundException cnfe) {
if (this.parent != null) {
// Ask to parent ClassLoader (can also throw a CNFE).
@@ -201,5 +202,13 @@
} catch (MalformedURLException mue) {
throw new CascadingIOException("Could not add repository", mue);
}
+ }
+
+ /**
+ * Adds a new URL
+ */
+
+ public void addURL(URL url) {
+ super.addURL(url);
}
}
1.2 +138 -100 cocoon-2.1/src/java/org/apache/cocoon/servlet/ParanoidCocoonServlet.java
Index: ParanoidCocoonServlet.java
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/java/org/apache/cocoon/servlet/ParanoidCocoonServlet.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ParanoidCocoonServlet.java 9 Mar 2003 00:09:37 -0000 1.1
+++ ParanoidCocoonServlet.java 3 Jun 2003 13:25:42 -0000 1.2
@@ -50,12 +50,20 @@
*/
package org.apache.cocoon.servlet;
-import org.apache.cocoon.components.classloader.RepositoryClassLoader;
-import org.apache.cocoon.util.IOUtils;
-
-import javax.servlet.ServletException;
import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.net.MalformedURLException;
import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServlet;
/**
* This is the entry point for Cocoon execution as an HTTP Servlet.
@@ -66,105 +74,135 @@
* of it.
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
+ * @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
* @version CVS $Id$
*/
-public class ParanoidCocoonServlet extends CocoonServlet {
+public class ParanoidCocoonServlet extends HttpServlet {
- protected RepositoryClassLoader repositoryLoader;
+ /**
+ * The name of the actual servlet class.
+ */
+ public static final String SERVLET_CLASS = "org.apache.cocoon.servlet.CocoonServlet";
+
+ private Servlet servlet;
+
+ private ClassLoader classloader;
- public ParanoidCocoonServlet() {
- super();
- // Override the parent class classloader
- this.repositoryLoader = new RepositoryClassLoader(new URL[] {}, this.getClass().getClassLoader());
- super.classLoader = this.repositoryLoader;
- }
-
- /**
- * This builds the important ClassPath used by this Servlet. It
- * does so in a Servlet Engine neutral way. It uses the
- * <code>ServletContext</code>'s <code>getRealPath</code> method
- * to get the Servlet 2.2 identified classes and lib directories.
- * It iterates through every file in the lib directory and adds
- * it to the classpath.
- *
- * Also, we add the files to the ClassLoader for the Cocoon system.
- * In order to protect ourselves from skitzofrantic classloaders,
- * we need to work with a known one.
- *
- * @param context The ServletContext to perform the lookup.
- *
- * @throws ServletException
- */
- protected String getClassPath()
- throws ServletException {
-
- StringBuffer buildClassPath = new StringBuffer();
- String classDirPath = getInitParameter("class-dir");
- String libDirPath = getInitParameter("lib-dir");
- String classDir;
- File root;
-
- if ((classDirPath != null) && !classDirPath.trim().equals("")) {
- classDir = classDirPath;
- } else {
- classDir = this.servletContext.getRealPath("/WEB-INF/classes");
- }
-
- if ((libDirPath != null) && !libDirPath.trim().equals("")) {
- root = new File(libDirPath);
- } else {
- root = new File(this.servletContext.getRealPath("/WEB-INF/lib"));
- }
-
- addClassLoaderDirectory(classDir);
-
- buildClassPath.append(classDir);
-
- if (root.isDirectory()) {
- File[] libraries = root.listFiles();
-
- for (int i = 0; i < libraries.length; i++) {
- String fullName = IOUtils.getFullFilename(libraries[i]);
- buildClassPath.append(File.pathSeparatorChar).append(fullName);
-
- addClassLoaderDirectory(fullName);
- }
- }
-
- buildClassPath.append(File.pathSeparatorChar)
- .append(System.getProperty("java.class.path"));
-
- buildClassPath.append(File.pathSeparatorChar)
- .append(getExtraClassPath());
-
- return buildClassPath.toString();
- }
-
- /**
- * Adds an URL to the classloader.
- */
- protected void addClassLoaderURL(URL url) {
- try {
- this.repositoryLoader.addURL(url);
- } catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug("Could not add URL" + url, e);
- }
- }
- }
-
- /**
- * Adds a directory to the classloader.
- */
- protected void addClassLoaderDirectory(String dir) {
- try {
- this.repositoryLoader.addDirectory(new File(dir));
- } catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug("Could not add directory" + dir, e);
- }
- }
- }
+ public void init(ServletConfig config) throws ServletException {
+
+ super.init(config);
+
+ // Create the classloader in which we will load the servlet
+ this.classloader = getClassLoader(this.getContextDir());
+
+ // Create the servlet
+ try {
+ Class servletClass = this.classloader.loadClass(SERVLET_CLASS);
+
+ this.servlet = (Servlet)servletClass.newInstance();
+
+ } catch(Exception e) {
+ throw new ServletException("Cannot load servlet " + SERVLET_CLASS, e);
+ }
+
+ // Always set the context classloader. JAXP uses it to find a ParserFactory,
+ // and thus fails if it's not set to the webapp classloader.
+ Thread.currentThread().setContextClassLoader(this.classloader);
+
+ // Inlitialize the actual servlet
+ initServlet(servlet);
+
+ }
+
+ /**
+ * Initialize the wrapped servlet. Subclasses (see {@link BootstrapServlet} change the
+ * <code>ServletConfig</code> given to the servlet.
+ *
+ * @param servlet the servlet to initialize
+ * @throws ServletException
+ */
+ protected void initServlet(Servlet servlet) throws ServletException {
+ this.servlet.init(getServletConfig());
+ }
+
+ /**
+ * Get the web application context directory.
+ *
+ * @return the context dir
+ * @throws ServletException
+ */
+ protected File getContextDir() throws ServletException {
+ String result = getServletContext().getRealPath("/");
+ if (result == null) {
+ throw new ServletException(this.getClass().getName() + " cannot run in an undeployed WAR file");
+ }
+ return new File(result);
+ }
+
+ /**
+ * Get the classloader that will be used to create the actual servlet. Its classpath is defined
+ * by the WEB-INF/classes and WEB-INF/lib directories in the context dir.
+ */
+ private ClassLoader getClassLoader(File contextDir) throws ServletException {
+ List urlList = new ArrayList();
+
+ try {
+ File classDir = new File(contextDir + "/WEB-INF/classes");
+ if (classDir.exists()) {
+ if (!classDir.isDirectory()) {
+ throw new ServletException(classDir + " exists but is not a directory");
+ }
+
+ URL classURL = classDir.toURL();
+ log("Adding class directory " + classURL);
+ urlList.add(classURL);
+
+ }
+
+ // List all .jar and .zip
+ File libDir = new File(contextDir + "/WEB-INF/lib");
+ File[] libraries = libDir.listFiles(
+ new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.endsWith(".zip") || name.endsWith(".jar");
+ }
+ }
+ );
+
+ for (int i = 0; i < libraries.length; i++) {
+ URL lib = libraries[i].toURL();
+ log("Adding class library " + lib);
+ urlList.add(lib);
+ }
+ } catch (MalformedURLException mue) {
+ throw new ServletException(mue);
+ }
+
+ URL[] urls = (URL[])urlList.toArray(new URL[urlList.size()]);
+
+ return ParanoidClassLoader.newInstance(urls, this.getClass().getClassLoader());
+ }
+
+ /**
+ * Service the request by delegating the call to the real servlet
+ */
+ public void service(ServletRequest request, ServletResponse response)
+ throws ServletException, IOException {
+
+ Thread.currentThread().setContextClassLoader(this.classloader);
+ this.servlet.service(request, response);
+ }
+
+ /**
+ * Destroy the actual servlet
+ */
+ public void destroy() {
+
+ Thread.currentThread().setContextClassLoader(this.classloader);
+ this.servlet.destroy();
+
+ super.destroy();
+ }
}