You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by cr...@apache.org on 2001/02/18 03:18:16 UTC

cvs commit: jakarta-tomcat-4.0/tester/src/bin tester.bat tester.sh

craigmcc    01/02/17 18:18:15

  Modified:    .        build.xml
               catalina/src/share/org/apache/catalina/core
                        StandardWrapper.java
               catalina/src/share/org/apache/catalina/loader
                        StandardClassLoader.java
               jasper   build.xml
               jasper/src/share/org/apache/jasper/compiler
                        TagLibraryInfoImpl.java TldLocationsCache.java
               jasper/src/share/org/apache/jasper/parser ParserUtils.java
               jasper/src/share/org/apache/jasper/runtime
                        PageContextImpl.java
               tester/src/bin tester.bat tester.sh
  Added:       jasper/src/share/org/apache/jasper/runtime
                        ServletResponseWrapperInclude.java
  Removed:     jasper/src/share/org/apache/jasper/compiler
                        ServletResponseWrapperInclude.java
  Log:
  Stage 3 of making Jasper work without an XML parser in the "lib"
  directory.  As you can see, it was a little more involved than originally
  planned.  Notes on what is going on:
  
  * A new directory, $CATALINA_HOME/jasper, contains the portions of Jasper
    that compile new JSP pages -- plus the XML parser that they need.
  
  * The jaxp.jar and crimson.jar files have been moved from "lib" to
    "jasper", so that they will not show up in the class loader hierarchy
    as seen by a web app.  Thus, an application that wants to run Xerces
    (by putting xerces.jar in WEB-INF/lib) should no longer have a problem.
  
  * The runtime portions of Jasper (i.e. the code needed by an already
    compiled JSP page) remains in the "lib" directory.  As you can see from
    the modified build.xml file, the current code organization is really
    awful - anyone interested in working on a complete overhaul?
  
  * Catalina was modified such that, *if and only if* a web application uses
    JSPs, a class loader that is a child of the web app class loader is
    created, picking up the contents of the "jasper" directory.
  
  * All Watchdog 4.0 tests currently pass.  I'm running other tests to
    make sure I didn't break anything accidentally, and would appreciate
    it if others did the same.
  
  Revision  Changes    Path
  1.18      +4 -0      jakarta-tomcat-4.0/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/build.xml,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- build.xml	2001/02/05 05:46:03	1.17
  +++ build.xml	2001/02/18 02:18:13	1.18
  @@ -56,6 +56,7 @@
       <mkdir dir="${tomcat.dist}"/>
       <mkdir dir="${tomcat.dist}/bin"/>
       <mkdir dir="${tomcat.dist}/conf"/>
  +    <mkdir dir="${tomcat.dist}/jasper"/>
       <mkdir dir="${tomcat.dist}/lib"/>
       <mkdir dir="${tomcat.dist}/logs"/>
       <mkdir dir="${tomcat.dist}/server"/>
  @@ -80,6 +81,9 @@
       </copy>
       <copy todir="${tomcat.dist}/conf">
         <fileset dir="${tomcat.build}/conf" />
  +    </copy>
  +    <copy todir="${tomcat.dist}/jasper">
  +      <fileset dir="${tomcat.build}/jasper" />
       </copy>
       <copy todir="${tomcat.dist}/lib">
         <fileset dir="${tomcat.build}/lib" />
  
  
  
  1.13      +66 -4     jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardWrapper.java
  
  Index: StandardWrapper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardWrapper.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- StandardWrapper.java	2001/01/23 02:51:15	1.12
  +++ StandardWrapper.java	2001/02/18 02:18:13	1.13
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardWrapper.java,v 1.12 2001/01/23 02:51:15 craigmcc Exp $
  - * $Revision: 1.12 $
  - * $Date: 2001/01/23 02:51:15 $
  + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardWrapper.java,v 1.13 2001/02/18 02:18:13 craigmcc Exp $
  + * $Revision: 1.13 $
  + * $Date: 2001/02/18 02:18:13 $
    *
    * ====================================================================
    *
  @@ -65,7 +65,9 @@
   package org.apache.catalina.core;
   
   
  +import java.io.File;
   import java.io.IOException;
  +import java.net.URL;
   import java.util.Enumeration;
   import java.util.HashMap;
   import javax.servlet.Servlet;
  @@ -86,6 +88,7 @@
   import org.apache.catalina.Request;
   import org.apache.catalina.Response;
   import org.apache.catalina.Wrapper;
  +import org.apache.catalina.loader.StandardClassLoader;
   import org.apache.catalina.util.Enumerator;
   import org.apache.catalina.util.InstanceSupport;
   
  @@ -101,7 +104,7 @@
    * make them efficient are counter-productive.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.12 $ $Date: 2001/01/23 02:51:15 $
  + * @version $Revision: 1.13 $ $Date: 2001/02/18 02:18:13 $
    */
   
   public final class StandardWrapper
  @@ -167,6 +170,12 @@
   
   
       /**
  +     * The specialized class loader for the Jasper JSP servlet.
  +     */
  +    private ClassLoader jasperLoader = null;
  +
  +
  +    /**
        * The context-relative URI of the JSP file for this servlet.
        */
       private String jspFile = null;
  @@ -715,6 +724,13 @@
   	          ("standardWrapper.containerServlet", getName()));
           }
   
  +        // Special case class loader for the Jasper JSP servlet
  +        if (this.name.equals(Constants.JSP_SERVLET_NAME)) {
  +            if (jasperLoader == null)
  +                jasperLoader = createJasperLoader(classLoader);
  +            classLoader = jasperLoader;
  +        }
  +
   	// Load the specified servlet class from the appropriate class loader
   	Class classClass = null;
   	try {
  @@ -902,6 +918,7 @@
   
   	// Deregister the destroyed instance
   	instance = null;
  +        jasperLoader = null;
   	fireContainerEvent("unload", this);
   
       }
  @@ -976,6 +993,51 @@
       protected void addDefaultMapper(String mapperClass) {
   
   	;	// No need for a default Mapper on a Wrapper
  +
  +    }
  +
  +
  +    /**
  +     * Create and return a custom class loader for the Jasper JSP servlet
  +     * that picks up the relevant classes from the "jasper" subdirectory
  +     * underneath "catalina.home".
  +     *
  +     * @param classLoader The web app class loader to be our parent
  +     *
  +     * @exception IllegalArgumentException if an error occurs building a
  +     *  URL for one of the repository JAR files
  +     */
  +    protected ClassLoader createJasperLoader(ClassLoader classLoader) {
  +
  +        // Create a new class loader with the webapp class loader as parent
  +        StandardClassLoader jasperLoader =
  +            new StandardClassLoader(classLoader);
  +
  +        // Accumulate the list of repositories to be added for this loader
  +        File directory = new File(System.getProperty("catalina.home"),
  +                                  "jasper");
  +        if (!directory.exists() || !directory.canRead() ||
  +            !directory.isDirectory())
  +            return (jasperLoader);
  +        String filenames[] = directory.list();
  +        for (int i = 0; i < filenames.length; i++) {
  +            if (!filenames[i].endsWith(".jar"))
  +                continue;
  +            File file = new File(directory, filenames[i]);
  +            try {
  +                URL url = new URL("file", null, file.getCanonicalPath());
  +                jasperLoader.addRepository(url.toString());
  +            } catch (IOException e) {
  +                throw new IllegalArgumentException(e.toString());
  +            }
  +        }
  +
  +        // Return the configured class loader
  +        if (debug >= 1) {
  +            log("Created Jasper Class Loader");
  +            log(jasperLoader.toString());
  +        }
  +        return (jasperLoader);
   
       }
   
  
  
  
  1.11      +9 -5      jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/StandardClassLoader.java
  
  Index: StandardClassLoader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/StandardClassLoader.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- StandardClassLoader.java	2001/02/08 01:58:06	1.10
  +++ StandardClassLoader.java	2001/02/18 02:18:13	1.11
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/StandardClassLoader.java,v 1.10 2001/02/08 01:58:06 craigmcc Exp $
  - * $Revision: 1.10 $
  - * $Date: 2001/02/08 01:58:06 $
  + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/StandardClassLoader.java,v 1.11 2001/02/18 02:18:13 craigmcc Exp $
  + * $Revision: 1.11 $
  + * $Date: 2001/02/18 02:18:13 $
    *
    * ====================================================================
    *
  @@ -109,7 +109,7 @@
    *
    * @author Craig R. McClanahan
    * @author Remy Maucherat
  - * @version $Revision: 1.10 $ $Date: 2001/02/08 01:58:06 $
  + * @version $Revision: 1.11 $ $Date: 2001/02/18 02:18:13 $
    */
   
   public class StandardClassLoader
  @@ -593,7 +593,11 @@
               sb.append(required.next().toString());
               sb.append("\r\n");
           }
  -        sb.append("\r\n");
  +        if (getParent() != null) {
  +            sb.append("----------> Parent Classloader:\r\n");
  +            sb.append(getParent().toString());
  +            sb.append("\r\n");
  +        }
           return (sb.toString());
   
       }
  
  
  
  1.14      +26 -7     jakarta-tomcat-4.0/jasper/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/jasper/build.xml,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- build.xml	2001/02/01 19:07:52	1.13
  +++ build.xml	2001/02/18 02:18:14	1.14
  @@ -39,8 +39,8 @@
       <!-- Shared Extensions -->
       <!--   Jasper needs the servlet API classes -->
       <copy file="${servlet.jar}" tofile="${jasper.build}/bin/servlet.jar"/>
  -    <!--   Jasper needs JAXP1.0/SAX2.0 compliant parser -->
  -    <copy file="${parser.jar}" 
  +    <!--   Jasper needs JAXP1.1/SAX2.0 compliant parser -->
  +    <copy file="${parser.jar}"
        tofile="${jasper.build}/lib/${jasper.jaxp.parser.jar}"/>
   
     </target>
  @@ -100,7 +100,7 @@
     <target name="deploy-prepare">
       <mkdir dir="${jasper.deploy}"/>
       <mkdir dir="${jasper.deploy}/bin"/>
  -    <mkdir dir="${jasper.deploy}/lib"/>
  +    <mkdir dir="${jasper.deploy}/jasper"/>
     </target>
   
   
  @@ -117,17 +117,36 @@
       <chmod perm="+x" file="${jasper.deploy}/bin/jspc.sh"/>
   
       <!-- Shared Extensions -->
  -    <copy todir="${jasper.deploy}/lib">
  +    <copy todir="${jasper.deploy}/jasper">
         <fileset dir="${jasper.build}/lib" />
       </copy>
   
     </target>
   
   
  -  <!-- ====================== DEPLOY: Create Jasper JAR =================== -->
  +  <!-- ====================== DEPLOY: Create Jasper JARs ================== -->
     <target name="deploy-main" depends="deploy-static">
  -    <jar  jarfile="${jasper.deploy}/lib/jasper.jar"
  -          basedir="${jasper.build}/classes"/>
  +    <jar  jarfile="${jasper.deploy}/jasper/jasper-compiler.jar">
  +      <fileset dir="${jasper.build}/classes">
  +        <include name="org/apache/jasper/compiler/**" />
  +        <include name="org/apache/jasper/parser/**" />
  +        <include name="org/apache/jasper/servlet/**" />
  +        <exclude name="org/apache/jasper/Constants.class" />
  +        <exclude name="org/apache/jasper/JasperException.class" />
  +        <include name="org/apache/jasper/*.class" />
  +      </fileset>
  +    </jar>
  +    <jar  jarfile="${jasper.deploy}/lib/jasper-runtime.jar">
  +      <fileset dir="${jasper.build}/classes">
  +        <include name="org/apache/jasper/Constants.class" />
  +        <include name="org/apache/jasper/JasperException.class" />
  +        <include name="org/apache/jasper/core/**" />
  +        <include name="org/apache/jasper/logging/**" />
  +        <include name="org/apache/jasper/resources/**" />
  +        <include name="org/apache/jasper/runtime/**" />
  +        <include name="org/apache/jasper/util/**" />
  +      </fileset>
  +    </jar>
     </target>
   
   
  
  
  
  1.20      +9 -10     jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/compiler/TagLibraryInfoImpl.java
  
  Index: TagLibraryInfoImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/compiler/TagLibraryInfoImpl.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- TagLibraryInfoImpl.java	2001/02/16 22:17:04	1.19
  +++ TagLibraryInfoImpl.java	2001/02/18 02:18:14	1.20
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/compiler/TagLibraryInfoImpl.java,v 1.19 2001/02/16 22:17:04 craigmcc Exp $
  - * $Revision: 1.19 $
  - * $Date: 2001/02/16 22:17:04 $
  + * $Header: /home/cvs/jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/compiler/TagLibraryInfoImpl.java,v 1.20 2001/02/18 02:18:14 craigmcc Exp $
  + * $Revision: 1.20 $
  + * $Date: 2001/02/18 02:18:14 $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -90,9 +90,6 @@
   import javax.servlet.jsp.tagext.VariableInfo;
   import javax.servlet.jsp.tagext.TagVariableInfo;
   
  -// import org.w3c.dom.*;
  -// import org.xml.sax.*;
  -
   import org.apache.jasper.JspCompilationContext;
   import org.apache.jasper.JasperException;
   import org.apache.jasper.Constants;
  @@ -214,7 +211,7 @@
   					new Object[] {location[0]}));
   	    }
   	    // Now parse the tld.
  -	    parseTLD(location[0], in);
  +	    parseTLD(ctxt, location[0], in);
   	} else {
   	    // Location points to a jar file
   	    // tag library in jar file
  @@ -231,7 +228,7 @@
   		jarFile = conn.getJarFile();
   		jarEntry = jarFile.getEntry(location[1]);
   		stream = jarFile.getInputStream(jarEntry);
  -		parseTLD(location[0], stream);
  +		parseTLD(ctxt, location[0], stream);
   		// FIXME @@@
   		// -- it seems that the JarURLConnection class caches JarFile 
   		// objects for particular URLs, and there is no way to get 
  @@ -263,14 +260,16 @@
       }
       
           
  -    private void parseTLD(String uri, InputStream in) 
  +    private void parseTLD(JspCompilationContext ctxt,
  +                          String uri, InputStream in) 
           throws JasperException
       {
   
           Vector tagVector = new Vector();
   
           // Create an iterator over the child elements of our <taglib> element
  -        ParserUtils pu = new ParserUtils();
  +        ClassLoader cl = ctxt.getClassLoader();
  +        ParserUtils pu = ParserUtils.createParserUtils(cl);
           TreeNode tld = pu.parseXMLDocument(uri, in);
           Iterator list = tld.findChildren();
   
  
  
  
  1.6       +3 -1      jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/compiler/TldLocationsCache.java
  
  Index: TldLocationsCache.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/compiler/TldLocationsCache.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- TldLocationsCache.java	2001/02/16 22:17:05	1.5
  +++ TldLocationsCache.java	2001/02/18 02:18:14	1.6
  @@ -155,7 +155,9 @@
           }
   
           // Parse the web application deployment descriptor
  -        ParserUtils pu = new ParserUtils();
  +        ClassLoader cl =
  +            (ClassLoader) ctxt.getAttribute(Constants.SERVLET_CLASS_LOADER);
  +        ParserUtils pu = ParserUtils.createParserUtils(cl);
           TreeNode webtld = pu.parseXMLDocument(WEB_XML, is);
           Iterator taglibs = webtld.findChildren("taglib");
           while (taglibs.hasNext()) {
  
  
  
  1.2       +148 -1    jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/parser/ParserUtils.java
  
  Index: ParserUtils.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/parser/ParserUtils.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ParserUtils.java	2001/02/16 07:14:34	1.1
  +++ ParserUtils.java	2001/02/18 02:18:15	1.2
  @@ -58,6 +58,15 @@
   import java.io.InputStream;
   import java.io.IOException;
   
  +import java.lang.reflect.InvocationTargetException;
  +import java.lang.reflect.Method;
  +
  +import java.net.MalformedURLException;
  +import java.net.URL;
  +import java.net.URLClassLoader;
  +
  +import java.util.HashMap;
  +
   import javax.xml.parsers.DocumentBuilder;
   import javax.xml.parsers.DocumentBuilderFactory;
   import javax.xml.parsers.ParserConfigurationException;
  @@ -86,7 +95,7 @@
    * use a separate class loader for the parser to be used.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2001/02/16 07:14:34 $
  + * @version $Revision: 1.2 $ $Date: 2001/02/18 02:18:15 $
    */
   
   public class ParserUtils {
  @@ -125,6 +134,12 @@
   
   
       /**
  +     * The class loader to use for accessing our XML parser.
  +     */
  +    protected ClassLoader classLoader = null;
  +
  +
  +    /**
        * An error handler for use when parsing XML documents.
        */
       protected ErrorHandler errorHandler = new MyErrorHandler();
  @@ -140,6 +155,16 @@
   
   
       /**
  +     * Return the class loader used to access our XML parser.
  +     */
  +    public ClassLoader getClassLoader() {
  +
  +        return (this.classLoader);
  +
  +    }
  +
  +
  +    /**
        * Parse the specified XML document, and return a <code>TreeNode</code>
        * that corresponds to the root node of the document tree.
        *
  @@ -158,12 +183,33 @@
           try {
               DocumentBuilderFactory factory =
                   DocumentBuilderFactory.newInstance();
  +            /*
  +            Class clazz =
  +             classLoader.loadClass("javax.xml.parsers.DocumentBuilderFactory");
  +            System.out.println("Loaded DBF from:");
  +            System.out.println(clazz.getClassLoader());
  +            Method method = clazz.getMethod("newInstance", new Class[0]);
  +            DocumentBuilderFactory factory = (DocumentBuilderFactory)
  +                method.invoke(null, new Object[0]);
  +            */
               factory.setNamespaceAware(true);
               factory.setValidating(true);
               DocumentBuilder builder = factory.newDocumentBuilder();
               builder.setEntityResolver(entityResolver);
               builder.setErrorHandler(errorHandler);
               document = builder.parse(is);
  +            /*
  +        } catch (ClassNotFoundException ex) {
  +            throw new JasperException("CNFE: " + ex); // FIXME
  +        } catch (IllegalAccessException ex) {
  +            throw new JasperException("IACE: " + ex); // FIXME
  +        } catch (IllegalArgumentException ex) {
  +            throw new JasperException("IARE: " + ex); // FIXME
  +        } catch (InvocationTargetException ex) {
  +            throw new JasperException("ITE: " + ex); // FIXME
  +        } catch (NoSuchMethodException ex) {
  +            throw new JasperException("NSME: " + ex); // FIXME
  +            */
   	} catch (ParserConfigurationException ex) {
               throw new JasperException
                   (Constants.getString("jsp.error.parse.xml",
  @@ -193,6 +239,18 @@
       }
   
   
  +    /**
  +     * Set the class loader used to access our XML parser.
  +     *
  +     * @param classLoader The new class loader
  +     */
  +    public void setClassLoader(ClassLoader classLoader) {
  +
  +        this.classLoader = classLoader;
  +
  +    }
  +
  +
       // ------------------------------------------------------ Protected Methods
   
   
  @@ -242,6 +300,95 @@
   
           // Return the completed TreeNode graph
           return (treeNode);
  +
  +    }
  +
  +
  +    // ------------------------------------------------------- Static Variables
  +
  +
  +    /**
  +     * The special class loaders for each web application's XML parser,
  +     * keyed by the web application class loader instance.  FIXME - this
  +     * probably interferes with garbage collection after an application reload.
  +     */
  +    private static HashMap classLoaders = new HashMap();
  +
  +
  +    // --------------------------------------------------------- Static Methods
  +
  +
  +    /**
  +     * Create (if necessary) and return an instance of ParserUtils that has
  +     * been loaded by our subordinate class loader (and therefore should have
  +     * access to the XML parser that is visible to repositories of that
  +     * class loader).
  +     *
  +     * @param parentLoader The web application class loader
  +     */
  +    public synchronized static ParserUtils createParserUtils
  +        (ClassLoader parentLoader) {
  +
  +        ParserUtils parserUtils = null;
  +        /*
  +        try {
  +            Class clazz = parentLoader.loadClass
  +                ("org.apache.jasper.parser.ParserUtils");
  +            parserUtils = (ParserUtils) clazz.newInstance();
  +            System.out.println("ParserUtils loaded by ClassLoader:\r\n" +
  +                               parserUtils.getClass().getClassLoader());
  +            parserUtils.setClassLoader(createClassLoader(parentLoader));
  +        } catch (ClassNotFoundException e) {
  +            System.out.println("createParserUtils:  ClassNotFoundException");
  +            e.printStackTrace(System.out);
  +        } catch (IllegalAccessException e) {
  +            System.out.println("createParserUtils:  IllegalAccessException");
  +            e.printStackTrace(System.out);
  +        } catch (InstantiationException e) {
  +            System.out.println("createParserUtils:  InstantiationException");
  +            e.printStackTrace(System.out);
  +        } catch (MalformedURLException e) {
  +            System.out.println("createParserUtils:  MalformedURLException");
  +            e.printStackTrace(System.out);
  +        }
  +        */
  +        parserUtils = new ParserUtils();
  +        parserUtils.setClassLoader(parentLoader);
  +        return (parserUtils);
  +
  +    }
  +
  +
  +    /**
  +     * Construct (if necessary) and return a class loader that has been
  +     * configured with the specified parent class loader, and repositories
  +     * as needed to access the required XML parser.
  +     *
  +     * @param parentLoader The web application class loader
  +     *
  +     * @exception MalformedURLException if we cannot create a valid URL for
  +     *  one of the required repositories
  +     */
  +    public synchronized static ClassLoader createClassLoader
  +        (ClassLoader parentLoader) throws MalformedURLException {
  +
  +        // Return any existing class loader for this web application
  +        URLClassLoader classLoader = (URLClassLoader)
  +            classLoaders.get(parentLoader);
  +        if (classLoader != null)
  +            return (classLoader);
  +
  +        // Construct, cache, and return a new class loader
  +        URL urls[] = new URL[2]; // FIXME
  +        urls[0] = new URL("file:///classes/jaxp.jar");
  +        urls[1] = new URL("file:///classes/crimson.jar");
  +        classLoader = new URLClassLoader(urls, parentLoader);
  +        classLoaders.put(parentLoader, classLoader);
  +        System.out.println("PUF:  createClassLoader:\r\n" + classLoader);
  +        urls = classLoader.getURLs();
  +        for (int i = 0; i < urls.length; i++)
  +            System.out.println("PUF:    url=" + urls[i]);
  +        return (classLoader);
   
       }
   
  
  
  
  1.9       +3 -4      jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/runtime/PageContextImpl.java
  
  Index: PageContextImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/runtime/PageContextImpl.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- PageContextImpl.java	2001/02/04 01:07:22	1.8
  +++ PageContextImpl.java	2001/02/18 02:18:15	1.9
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/runtime/PageContextImpl.java,v 1.8 2001/02/04 01:07:22 glenn Exp $
  - * $Revision: 1.8 $
  - * $Date: 2001/02/04 01:07:22 $
  + * $Header: /home/cvs/jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/runtime/PageContextImpl.java,v 1.9 2001/02/18 02:18:15 craigmcc Exp $
  + * $Revision: 1.9 $
  + * $Date: 2001/02/18 02:18:15 $
    *
    * ====================================================================
    *
  @@ -88,7 +88,6 @@
   
   import org.apache.jasper.Constants;
   import org.apache.jasper.logging.Logger;
  -import org.apache.jasper.compiler.ServletResponseWrapperInclude;
   
   /**
    * Implementation of the PageContext class from the JSP spec.
  
  
  
  1.1                  jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/runtime/ServletResponseWrapperInclude.java
  
  Index: ServletResponseWrapperInclude.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/runtime/ServletResponseWrapperInclude.java,v 1.1 2001/02/18 02:18:15 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2001/02/18 02:18:15 $
   *
   * ====================================================================
   * 
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */ 
  
  package org.apache.jasper.runtime;
  
  import java.lang.IllegalStateException;
  import java.io.PrintWriter;
  
  import javax.servlet.*;
  import javax.servlet.http.*;
  import javax.servlet.jsp.*;
  
  /**
   * ServletResponseWrapper used for the JSP 'include' action.
   *
   * This 'wrapped' response object is passed as the second argument 
   * to the internal RequestDispatcher.include(). It channels
   * all output text into the current JspWriter.
   *
   * @author Pierre Delisle
   */
  
  public class ServletResponseWrapperInclude
      extends HttpServletResponseWrapper
  {
      /**
       * The PrintWriter writes all output to the JspWriter of the 
       * including page.
       */
      PrintWriter printWriter;
  
      public ServletResponseWrapperInclude(ServletResponse response, 
  					 JspWriter jspWriter) 
      {
  	super((HttpServletResponse)response);
  	this.printWriter = new PrintWriter(jspWriter);
      }
  
      /**
       * Returns a wrapper around the JspWriter of the including page.
       */
      public java.io.PrintWriter getWriter()
  	throws java.io.IOException 
      {
  	return printWriter;
      }
  
      public ServletOutputStream getOutputStream()
  	throws java.io.IOException
      {
  	throw new IllegalStateException();
      }
  }
  
  
  
  1.3       +2 -2      jakarta-tomcat-4.0/tester/src/bin/tester.bat
  
  Index: tester.bat
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/tester/src/bin/tester.bat,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- tester.bat	2001/02/01 16:53:02	1.2
  +++ tester.bat	2001/02/18 02:18:15	1.3
  @@ -14,7 +14,7 @@
   rem
   rem   JAVA_HOME     Must point at your Java Development Kit installation.
   rem
  -rem $Id: tester.bat,v 1.2 2001/02/01 16:53:02 craigmcc Exp $
  +rem $Id: tester.bat,v 1.3 2001/02/18 02:18:15 craigmcc Exp $
   rem ---------------------------------------------------------------------------
   
   
  @@ -59,7 +59,7 @@
   
   rem ----- Set Up The Runtime Classpath ----------------------------------------
   
  -set CP=%CATALINA_HOME%\webapps\tester\WEB-INF\lib\tester.jar;%CATALINA_HOME%\lib\jaxp.jar;%CATALINA_HOME%\lib\crimson.jar;%ANT_HOME%\lib\ant.jar
  +set CP=%CATALINA_HOME%\webapps\tester\WEB-INF\lib\tester.jar;%CATALINA_HOME%\server\jaxp.jar;%CATALINA_HOME%\server\crimson.jar;%ANT_HOME%\lib\ant.jar
   set CLASSPATH=%CP%
   echo Using CLASSPATH: %CLASSPATH%
   
  
  
  
  1.2       +2 -2      jakarta-tomcat-4.0/tester/src/bin/tester.sh
  
  Index: tester.sh
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/tester/src/bin/tester.sh,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- tester.sh	2000/12/18 05:06:12	1.1
  +++ tester.sh	2001/02/18 02:18:15	1.2
  @@ -12,7 +12,7 @@
   #
   #   JAVA_HOME     Must point at your Java Development Kit installation.
   #
  -# $Id: tester.sh,v 1.1 2000/12/18 05:06:12 craigmcc Exp $
  +# $Id: tester.sh,v 1.2 2001/02/18 02:18:15 craigmcc Exp $
   # -----------------------------------------------------------------------------
   
   
  @@ -37,7 +37,7 @@
   
   # ----- Set Up The System Classpath -------------------------------------------
   
  -CP=$CATALINA_HOME/webapps/tester/WEB-INF/lib/tester.jar:$CATALINA_HOME/lib/jaxp.jar:$CATALINA_HOME/lib/crimson.jar:$ANT_HOME/lib/ant.jar
  +CP=$CATALINA_HOME/webapps/tester/WEB-INF/lib/tester.jar:$CATALINA_HOME/server/jaxp.jar:$CATALINA_HOME/server/crimson.jar:$ANT_HOME/lib/ant.jar
   
   echo Using CLASSPATH: $CP