sylvain 2002/06/11 06:47:36 Modified: . changes.xml src/java/org/apache/cocoon/servlet CocoonServlet.java ParanoidCocoonServlet.java src/webapp/WEB-INF web.xml Log: Solve some classloader issues Revision Changes Path 1.187 +6 -1 xml-cocoon2/changes.xml Index: changes.xml =================================================================== RCS file: /home/cvs/xml-cocoon2/changes.xml,v retrieving revision 1.186 retrieving revision 1.187 diff -u -r1.186 -r1.187 --- changes.xml 10 Jun 2002 09:02:07 -0000 1.186 +++ changes.xml 11 Jun 2002 13:47:36 -0000 1.187 @@ -38,6 +38,11 @@ </devs> <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="CH" type="add" due-to="Roger I Martin PhD" due-to-email="[EMAIL PROTECTED]"> ESQL: Added support for reading BLOBs from database. </action> 1.28 +56 -90 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.27 retrieving revision 1.28 diff -u -r1.27 -r1.28 --- CocoonServlet.java 6 Jun 2002 20:47:23 -0000 1.27 +++ CocoonServlet.java 11 Jun 2002 13:47:36 -0000 1.28 @@ -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,12 +205,18 @@ 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; @@ -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()) { @@ -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); } } } @@ -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(); @@ -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(); 1.6 +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.6 diff -u -r1.5 -r1.6 --- ParanoidCocoonServlet.java 22 Feb 2002 07:03:55 -0000 1.5 +++ ParanoidCocoonServlet.java 11 Jun 2002 13:47:36 -0000 1.6 @@ -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); + } + } + } } 1.13 +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.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- web.xml 1 Jun 2002 14:44:42 -0000 1.12 +++ web.xml 11 Jun 2002 13:47:36 -0000 1.13 @@ -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]