sylvain 2002/06/11 06:45:37
Modified: . Tag: cocoon_2_0_3_branch changes.xml
src/java/org/apache/cocoon/servlet Tag: cocoon_2_0_3_branch
CocoonServlet.java ParanoidCocoonServlet.java
src/webapp/WEB-INF Tag: cocoon_2_0_3_branch web.xml
Log:
Solve some classloader issues
Revision Changes Path
No revision
No revision
1.138.2.19 +6 -1 xml-cocoon2/changes.xml
Index: changes.xml
===================================================================
RCS file: /home/cvs/xml-cocoon2/changes.xml,v
retrieving revision 1.138.2.18
retrieving revision 1.138.2.19
diff -u -r1.138.2.18 -r1.138.2.19
--- changes.xml 6 Jun 2002 08:47:40 -0000 1.138.2.18
+++ changes.xml 11 Jun 2002 13:45:36 -0000 1.138.2.19
@@ -39,6 +39,11 @@
<release version="@version@" date="@date@">
+ <action dev="SW" type="update">
+ CocoonServlet no longer builds its own classloader. Also, it no more sets the
thread's context
+ classloader unless the "init-classloader" parameter is true. To have Cocoon use
its own classloader,
+ use the ParanoidCocoonServlet.
+ </action>
<action dev="VG" type="fix" fixes-bug="9539" due-to="Stuart Roebuck"
due-to-email="[EMAIL PROTECTED]">
ResourceReader incorrectly advertised byte ranges support.
</action>
No revision
No revision
1.19.2.5 +112 -146
xml-cocoon2/src/java/org/apache/cocoon/servlet/CocoonServlet.java
Index: CocoonServlet.java
===================================================================
RCS file:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/servlet/CocoonServlet.java,v
retrieving revision 1.19.2.4
retrieving revision 1.19.2.5
diff -u -r1.19.2.4 -r1.19.2.5
--- CocoonServlet.java 6 Jun 2002 20:49:00 -0000 1.19.2.4
+++ CocoonServlet.java 11 Jun 2002 13:45:37 -0000 1.19.2.5
@@ -68,7 +68,6 @@
import org.apache.cocoon.ResourceNotFoundException;
import org.apache.cocoon.ConnectionResetException;
import org.apache.cocoon.Cocoon;
-import org.apache.cocoon.components.classloader.RepositoryClassLoader;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.http.HttpContext;
import org.apache.cocoon.environment.http.HttpEnvironment;
@@ -161,14 +160,16 @@
private String defaultFormEncoding;
protected ServletContext servletContext;
- protected RepositoryClassLoader classLoader;
+
+ /** The classloader that will be set as the context classloader if
init-classloader is true */
+ protected ClassLoader classLoader = this.getClass().getClassLoader();
+ protected boolean initClassLoader = false;
private String parentComponentManagerClass;
private String requestFactoryClass;
protected String forceLoadParameter;
protected String forceSystemProperty;
- private boolean addClassDirs;
/**
* If true or not set, this class will try to catch and handle all Cocoon
exceptions.
@@ -204,16 +205,22 @@
throws ServletException {
super.init(conf);
-
- // Force context classloader so that JAXP can work correctly
- // (see javax.xml.parsers.FactoryFinder.findClassLoader())
- try {
-
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
- } catch (Exception e){}
+
+ final String initClassLoaderParam =
conf.getInitParameter("init-classloader");
+ this.initClassLoader = "true".equalsIgnoreCase(initClassLoaderParam) ||
+ "yes".equalsIgnoreCase(initClassLoaderParam);
+
+ if (this.initClassLoader) {
+ // Force context classloader so that JAXP can work correctly
+ // (see javax.xml.parsers.FactoryFinder.findClassLoader())
+ try {
+ Thread.currentThread().setContextClassLoader(this.classLoader);
+ } catch (Exception e){}
+ }
String value;
- // FIXME (VG): We shouldn't have to specify these. Need to override
+ // FIXME (VG): We shouldn't have to specify these. Need to override
// jaxp implementation of weblogic before initializing logger.
// This piece of code is also required in the Cocoon class.
value = System.getProperty("javax.xml.parsers.SAXParserFactory");
@@ -302,14 +309,6 @@
this.forceSystemProperty = conf.getInitParameter("force-property");
- value = conf.getInitParameter("init-classloader");
- this.addClassDirs = "true".equalsIgnoreCase(value) ||
"yes".equalsIgnoreCase(value);
- if (value == null) {
- if (log.isDebugEnabled()) {
- log.debug("init-classloader was not set - defaulting to false");
- }
- }
-
// add work directory
if ((workDirParam != null) && (!workDirParam.trim().equals(""))) {
if (log.isDebugEnabled()) {
@@ -425,14 +424,14 @@
}
}
- value = conf.getInitParameter("manage-exceptions");
+ 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.createCocoon();
}
@@ -441,9 +440,12 @@
*/
public void destroy()
{
- try {
- Thread.currentThread().setContextClassLoader(classLoader);
- } catch (Exception e){}
+ if (this.initClassLoader)
+ {
+ try {
+ Thread.currentThread().setContextClassLoader(this.classLoader);
+ } catch (Exception e){}
+ }
if (this.cocoon != null)
{
@@ -453,13 +455,22 @@
this.disposeCocoon();
}
}
+
+ /**
+ * Adds an URL to the classloader. Does nothing here, but is
+ * overriden in {@link ParanoidCocoonServlet}.
+ */
+ protected void addClassLoaderURL(URL URL) {
+ // Nothing
+ }
- /**
- * get the classloader to use for Cocoon instantiation
- */
- protected RepositoryClassLoader buildInitClassLoader() {
- return new RepositoryClassLoader(new URL[] {},
this.getClass().getClassLoader());
- }
+ /**
+ * Adds a directory to the classloader. Does nothing here, but is
+ * overriden in {@link ParanoidCocoonServlet}.
+ */
+ protected void addClassLoaderDirectory(String dir) {
+ // Nothing
+ }
/**
* This builds the important ClassPath used by this Servlet. It
@@ -494,15 +505,7 @@
if (classDir != null) {
buildClassPath.append(classDir);
- if (this.addClassDirs) {
- try {
- classLoader.addDirectory(new File(classDir));
- } catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug("Could not add directory" + classDir, e);
- }
- }
- }
+ addClassLoaderDirectory(classDir);
}
} else {
// New(ish) method for war'd deployments
@@ -532,15 +535,7 @@
if (classDirURL != null) {
buildClassPath.append(classDirURL.toExternalForm());
- if (this.addClassDirs) {
- try {
- classLoader.addURL(classDirURL);
- } catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug("Could not add directory " + classDirURL, e);
- }
- }
- }
+ addClassLoaderURL(classDirURL);
}
}
@@ -553,18 +548,10 @@
File[] libraries = root.listFiles();
Arrays.sort(libraries);
for (int i = 0; i < libraries.length; i++) {
- buildClassPath.append(File.pathSeparatorChar)
- .append(IOUtils.getFullFilename(libraries[i]));
+ String fullName = IOUtils.getFullFilename(libraries[i]);
+ buildClassPath.append(File.pathSeparatorChar).append(fullName);
- if (this.addClassDirs) {
- try {
- classLoader.addDirectory(libraries[i]);
- } catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug("Could not add file" +
IOUtils.getFullFilename(libraries[i]));
- }
- }
- }
+ addClassLoaderDirectory(fullName);
}
}
@@ -683,15 +670,7 @@
}
sb.append(s);
- if (this.addClassDirs) {
- try {
- classLoader.addDirectory(s.toString());
- } catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug("Could not add " + s.toString());
- }
- }
- }
+ addClassLoaderDirectory(s);
} else {
if (s.indexOf("${") != -1) {
String path = StringUtils.replaceToken(s);
@@ -699,15 +678,7 @@
if (log.isDebugEnabled()) {
log.debug ("extraClassPath is not absolute replacing
using token: [" + s + "] : " + path);
}
- if (this.addClassDirs) {
- try {
- classLoader.addDirectory(path);
- } catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug("Could not add " + path);
- }
- }
- }
+ addClassLoaderDirectory(path);
} else {
String path = null;
if (this.servletContextPath != null) {
@@ -722,15 +693,7 @@
}
}
sb.append(path);
- if (this.addClassDirs) {
- try {
- classLoader.addDirectory(path);
- } catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug("Could not add " + path);
- }
- }
- }
+ addClassLoaderDirectory(path);
}
}
}
@@ -845,7 +808,7 @@
log.error(msg, mue);
throw new ServletException(msg, mue);
}
-
+
if (result == null) {
String msg = "Init parameter 'configuration' doesn't name an existing
resource : " + usedFileName;
log.error(msg);
@@ -935,9 +898,11 @@
/* HACK for reducing class loader problems.
*/
/* example: xalan extensions fail if someone adds xalan jars in
tomcat3.2.1/lib */
- try {
- Thread.currentThread().setContextClassLoader(classLoader);
- } catch (Exception e){}
+ if (this.initClassLoader) {
+ try {
+ Thread.currentThread().setContextClassLoader(this.classLoader);
+ } catch (Exception e){}
+ }
// This is more scalable
long start = System.currentTimeMillis();
@@ -953,10 +918,10 @@
// Check if cocoon was initialized
if (this.cocoon == null) {
- if(manageExceptions){
+ if(manageExceptions){
res.reset();
- SimpleNotifyingBean n= new SimpleNotifyingBean(this);
+ SimpleNotifyingBean n = new SimpleNotifyingBean(this);
n.setType("fatal");
n.setTitle("Internal servlet error");
n.setSource("Cocoon servlet");
@@ -970,11 +935,11 @@
}
else{
res.sendError
- (HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ (HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"The Cocoon engine said it failed to process the request for an
unknown reason." );
res.flushBuffer();
return;
- }
+ }
}
@@ -1036,51 +1001,51 @@
} else {
//NKB Should not get here?
log.fatalError("The Cocoon engine said it failed to process the
request for an unknown reason.");
-
- if(manageExceptions){
- res.reset();
- SimpleNotifyingBean n = new SimpleNotifyingBean(this);
- n.setType("error");
+ if(manageExceptions){
+ res.reset();
+
+ SimpleNotifyingBean n = new SimpleNotifyingBean(this);
+ n.setType("error");
n.setTitle("Cocoon confusion");
- n.setSource("Cocoon servlet");
+ n.setSource("Cocoon servlet");
n.setMessage("Cocoon engine failed in process.");
n.setDescription("The Cocoon engine said it failed to process
the request for an unknown reason.");
- n.addExtraDescription("request-uri", request.getRequestURI());
- n.addExtraDescription("path-info", uri);
-
+ n.addExtraDescription("request-uri", request.getRequestURI());
+ n.addExtraDescription("path-info", uri);
+
res.setContentType("text/html");
res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
Notifier.notify(n, res.getOutputStream(), "text/html");
}
else{
res.sendError
- (HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ (HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"The Cocoon engine said it failed to process the request
for an unknown reason." );
res.flushBuffer();
- return;
+ return;
}
-
+
}
} catch (ResourceNotFoundException rse) {
if (log.isWarnEnabled()) {
log.warn("The resource was not found", rse);
}
- if(manageExceptions){
- res.reset();
+ if(manageExceptions){
+ res.reset();
+
+ SimpleNotifyingBean n = new SimpleNotifyingBean(this);
+ n.setType("resource-not-found");
+ n.setTitle("Resource not found");
+ n.setSource("Cocoon servlet");
+ n.setMessage("Resource not found");
+ n.setDescription("The requested URI \""
+ + request.getRequestURI()
+ + "\" was not found.");
+ n.addExtraDescription("request-uri", request.getRequestURI());
+ n.addExtraDescription("path-info", uri);
- SimpleNotifyingBean n = new SimpleNotifyingBean(this);
- n.setType("resource-not-found");
- n.setTitle("Resource not found");
- n.setSource("Cocoon servlet");
- n.setMessage("Resource not found");
- n.setDescription("The requested URI \""
- + request.getRequestURI()
- + "\" was not found.");
- n.addExtraDescription("request-uri", request.getRequestURI());
- n.addExtraDescription("path-info", uri);
-
res.setContentType("text/html");
res.setStatus(HttpServletResponse.SC_NOT_FOUND);
Notifier.notify(n, res.getOutputStream(), "text/html");
@@ -1089,7 +1054,7 @@
res.sendError
(HttpServletResponse.SC_NOT_FOUND, "Resource not found." );
res.flushBuffer();
- return;
+ return;
}
} catch (ConnectionResetException cre) {
@@ -1104,19 +1069,19 @@
if (log.isErrorEnabled()) {
log.error("Problem with Cocoon servlet", e);
}
-
- if(manageExceptions){
- res.reset();
-
- HashMap extraDescriptions = new HashMap(3);
- extraDescriptions.put("request-uri", request.getRequestURI());
- extraDescriptions.put("path-info", uri);
- StringWriter writer = new StringWriter();
- e.printStackTrace(new PrintWriter(writer));
- extraDescriptions.put("stack-trace",writer.toString());
- Notifying n=new DefaultNotifyingBuilder().build(
- this, e, "fatal","Internal server error","Cocoon
servlet",null,null,extraDescriptions);
+ if(manageExceptions){
+ res.reset();
+
+ HashMap extraDescriptions = new HashMap(3);
+ extraDescriptions.put("request-uri", request.getRequestURI());
+ extraDescriptions.put("path-info", uri);
+ StringWriter writer = new StringWriter();
+ e.printStackTrace(new PrintWriter(writer));
+ extraDescriptions.put("stack-trace",writer.toString());
+
+ Notifying n=new DefaultNotifyingBuilder().build(
+ this, e, "fatal","Internal server error","Cocoon
servlet",null,null,extraDescriptions);
res.setContentType("text/html");
res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
@@ -1124,11 +1089,11 @@
}
else{
res.sendError
- (HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ (HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Internal server error.");
res.flushBuffer();
- return;
- }
+ return;
+ }
}
long end = System.currentTimeMillis();
@@ -1157,14 +1122,14 @@
} finally {
if (ctxMap != null) ctxMap.clear();
try{
- ServletOutputStream out = res.getOutputStream();
- out.flush();
- out.close();
- }
+ ServletOutputStream out = res.getOutputStream();
+ out.flush();
+ out.close();
+ }
catch(Exception e){
- log.error("Cocoon servlet threw an Exception while trying to close
stream.", e);
+ log.error("Cocoon servlet threw an Exception while trying to close
stream.", e);
}
-
+
}
}
@@ -1241,13 +1206,14 @@
*/
private synchronized void createCocoon()
throws ServletException {
- this.classLoader = this.buildInitClassLoader();
/* HACK for reducing class loader problems.
*/
/* example: xalan extensions fail if someone adds xalan jars in
tomcat3.2.1/lib */
- try {
- Thread.currentThread().setContextClassLoader(this.classLoader);
- } catch (Exception e){}
+ if (this.initClassLoader) {
+ try {
+ Thread.currentThread().setContextClassLoader(this.classLoader);
+ } catch (Exception e){}
+ }
this.updateEnvironment();
this.forceLoad();
@@ -1319,7 +1285,7 @@
* Gets the current cocoon object. Reload cocoon if configuration
* changed or we are reloading.
*
- * @returns Cocoon
+ * @return Cocoon
*/
private Cocoon getCocoon(final String pathInfo, final String reloadParam)
throws ServletException {
1.5.2.1 +42 -13
xml-cocoon2/src/java/org/apache/cocoon/servlet/ParanoidCocoonServlet.java
Index: ParanoidCocoonServlet.java
===================================================================
RCS file:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/servlet/ParanoidCocoonServlet.java,v
retrieving revision 1.5
retrieving revision 1.5.2.1
diff -u -r1.5 -r1.5.2.1
--- ParanoidCocoonServlet.java 22 Feb 2002 07:03:55 -0000 1.5
+++ ParanoidCocoonServlet.java 11 Jun 2002 13:45:37 -0000 1.5.2.1
@@ -50,10 +50,12 @@
*/
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.net.URL;
/**
* This is the entry point for Cocoon execution as an HTTP Servlet.
@@ -69,6 +71,15 @@
public class ParanoidCocoonServlet extends CocoonServlet {
+ protected RepositoryClassLoader repositoryLoader;
+
+ 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
@@ -106,11 +117,7 @@
root = new File(this.servletContext.getRealPath("/WEB-INF/lib"));
}
- try {
- classLoader.addDirectory(new File(classDir));
- } catch (Exception e) {
- log.debug("Could not add directory" + classDir, e);
- }
+ addClassLoaderDirectory(classDir);
buildClassPath.append(classDir);
@@ -118,14 +125,10 @@
File[] libraries = root.listFiles();
for (int i = 0; i < libraries.length; i++) {
- buildClassPath.append(File.pathSeparatorChar)
- .append(IOUtils.getFullFilename(libraries[i]));
+ String fullName = IOUtils.getFullFilename(libraries[i]);
+ buildClassPath.append(File.pathSeparatorChar).append(fullName);
- try {
- classLoader.addDirectory(libraries[i]);
- } catch (Exception e) {
- log.debug("Could not add file" +
IOUtils.getFullFilename(libraries[i]));
- }
+ addClassLoaderDirectory(fullName);
}
}
@@ -137,5 +140,31 @@
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);
+ }
+ }
+ }
}
No revision
No revision
1.8.2.3 +3 -4 xml-cocoon2/src/webapp/WEB-INF/web.xml
Index: web.xml
===================================================================
RCS file: /home/cvs/xml-cocoon2/src/webapp/WEB-INF/web.xml,v
retrieving revision 1.8.2.2
retrieving revision 1.8.2.3
diff -u -r1.8.2.2 -r1.8.2.3
--- web.xml 6 Jun 2002 08:47:40 -0000 1.8.2.2
+++ web.xml 11 Jun 2002 13:45:37 -0000 1.8.2.3
@@ -38,10 +38,9 @@
</init-param>
<!--
- This parameter tells cocoon to load all the required libraries into
- it's own classloader instead of trusting the Servlet Vendor's
- classloader. If you experience strange classloader issues,
- try setting this parameter to "true".
+ This parameter tells cocoon to set the thread's context classloader to
+ its own classloader. If you experience strange classloader issues,
+ try setting this parameter to "true" or using ParanoidCocoonServlet.
-->
<init-param>
<param-name>init-classloader</param-name>
----------------------------------------------------------------------
In case of troubles, e-mail: [EMAIL PROTECTED]
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]