Cocoon Tips and Tricks

This FlashGuideTM provides various tips and tricks for Apache Cocoon 2.x. I hope you find them useful and time-saving.


The sitemap handler's sitemap is not available

  1. Any time you get the dreaded "The sitemap handler's sitemap is not available" error, you MUST CHECK THE LOGS. The logs are found in the WEB-INF/logs subdirectory of the cocoon web application. Look for the most recent cocoon*.log and find the stack trace. If you want to post an erorr to the cocoon mailing list, ALWAYS post the stack trace you find in your error logs.
  2. Another thing to try is to delete Tomcat's work directory for cocoon. The right directory can be found at $TOMCAT_HOME/work/[hostname][webappname] (for Tomcat 3.2.x) or $CATALINA_HOME/work/[hostname]/[webappname] (for Tomcat 4.x), where [webappname] refers to the name of your cocoon web application (default is cocoon, but you might have changed it like I do). Stop Tomcat, delete this directory, restart Tomcat and try Cocoon again. You might be suprised.

Cocoon Database Pooling

If you want to take advantage of Cocoon pooling, you need to edit both web.xml and cocoon.xconf. In this example, I'll show you how to add MySQL and Oracle database pool2 to Cocoon.

  1. Edit the load-class section of web.xml (found in Cocoon's WEB-INF directory) and make sure the MySQL driver gets preloaded during Cocoon's initiation:
        <init-param>
          <param-name>load-class</param-name>
          <param-value>
          <!-- Example for an Oracle database driver -->
          oracle.jdbc.driver.OracleDriver
          <!-- Example for a MySQL database driver -->
          org.gjt.mm.mysql.Driver
          </param-value>
          <!-- Add your other drivers here -->
        </init-param>
       

    If your Cocoon installation does not have the IBM WebSphere and HSQL drivers commented out, and you don't plan on using them, comment them out. Otherwise, you'll get errors in cocoon's log.

  2. Edit cocoon.xconf so that Cocoon will actually create the pools using the database connection information you provide:
  3.   <datasources>
        <jdbc name="test_mysql_pool">
          <pool-controller min="5" max="10"/>
          <auto-commit>true</auto-commit>
          <dburl>jdbc:mysql://[hostname]/[database]</dburl>
          <user>[user]</user>
          <password>[password]</password>
        </jdbc>
        <jdbc name="test_oracle_pool">
          <!-- Don't forget the oradb parameter for Oracle!!! -->
          <pool-controller min="5" max="10" oradb="true"/>
          <auto-commit>true</auto-commit>
          <dburl>jdbc:oracle:thin:@[hostname]:[port]:[tnsname]</dburl>
          <user>[user]</user>
          <password>[password]</password>
        </jdbc>
      </datasources>
       

    Of course, substitute your values for the bracketed parts

  4. Finally, you have to make sure that your database JDBC jars are visible to Cocoon. There are three ways to do this - choose ONE of them:

    1. Edit your servlet engines startup scrips so that the database jars are part of its classpath. For examples, on Tomcat 3.2.x you would edit tomcat.sh in the staticClasspath section ike this (for Oracle and MySQL):
      CLASSPATH=$CLASSPATH:$TOMCAT_HOME/lib/mysql_comp.jar
      CLASSPATH=$CLASSPATH:$TOMCAT_HOME/lib/OraThinDriver.8.1.7.jar
          

      Replace $TOMCAT_HOME with something else if you've chosen to keep the jars somewhere besides Tomcat's lib directory

    2. You can also put the database jars in the lib directory under Cocoon's WEB-INF directory. This will insure that Cocoon can find them.
    3. Finally, you can keep them out of both Cocoon's and the servlet engine's directory structure but still have them accessible to Cocoon by modifying the extra-classpath section of Cocoon's web.xml as follows:
          <init-param>
            <param-name>extra-classpath</param-name>
            <param-value>WEB-INF/extra-classes1:/[ABSOLUTE-PATH-TO]/mysql_comp.jar</param-value>
            <param-value>WEB-INF/extra-classes1:/[ABSOLUTE-PATH-TO]/OraThinDriver.8.1.7.jar</param-value>
          </init-param>
          

  5. If you want to use a connection from your new pool in an XSP using the ESQL taglib, then you'll need something like this:
    <?xml version="1.0" encoding="ISO-8859-1"?> 
     
    <xsp:page language="java"
       xmlns:xsp="http://apache.org/xsp"
       xmlns:esql="http://apache.org/cocoon/SQL/v2"
    >  
       
    <page> 
        
     <title>Db Connection Test</title>
       <content>
        <esql:connection> 
         <esql:pool>test_mysql_pool</esql:pool> 
         <esql:execute-query> 
           <esql:query>
            ... // your SQL query goes here
           </esql:query>
           <esql:results> 
             <esql:row-results> 
              ... // handle your results here
             </esql:row-results>
           </esql:results>
         </esql:execute-query>
        </esql:connection>
       </content>
      </page>
    </xsp:page>
       

Running multiple instances of Cocoon

Of course you can. What I like to do when I use Tomcat, is to rename cocoon.war to ROOT.war and restart Tomcat so that cocoon becomes the default web application. This only works, of course, if you don't already have plans for the default webapp.

  1. If you want to create multiple web applications that all reference the same document base, edit Tomcat's server.xml thus:
       <Context docBase="cocoon.war" root="webapp1" debug="0"/>
       <Context docBase="cocoon.war" root="webapp2" debug="0"/>
       <Context docBase="cocoon.war" root="webapp3" debug="0"/>
        

    This only works if you want all the web applications to share a common set of directories. If you don't want that, then you will have to rename cocoon.war to [new_webapp_name].war and restart Tomcat.


Removing 'cocoon' from your URL base

Some people, myself included, do not like to keep seeing "cocoon" in their URLs. There are a few ways to handle this that I've tried, and probably more besides.

  1. Copy $TOMCAT_HOME/webapps/cocoon to $TOMCAT_HOME/webapps/ROOT. This works if you are not already using the ROOT web application. You also should make sure to check all your links if you are using sub sitemaps. I have encountered a few problems.
  2. Point the docBase of the ROOT web application to the location of the cocoon web app. Again, this works only if you are not already using the ROOT web app. Edit $TOMCAT_HOME/conf/server.xml like this:
       <Context path="" docBase="cocoon" debug="0" reloadable="true"/>
       
  3. Front Tomcat with Apache (as described in my other FlashGuides) and use mod_rewrite to eliminate the cocoon.

Running Cocoon on a headless Unix box

If you have trouble getting Cocoon to run on a Unix box that has no X Server running, you have several choices.

  1. To simply remove Cocoon's dependency on an X Server, and if you don't plan on using any SVG stuff, comment out or delete from sitemap.xmap the three SVG serializer entries (svgxml, svg2jpeg, svg2png) and the pipeline entries that use them. Then restart your servlet container. Note that if you are using Tomcat, be sure to delete the $TOMCAT_HOME/work/localhost/cocoon directory before starting it back up again.
  2. To install xvfb, follow these instructions:

    1. Download xvfb from http://www.xfree86.org
    2. Install Xvfb per the instructions for your platform
    3. Create a startup script so that Xvfb always starts when the machine boots. Alternatively, you could include this just in the Tomcat startup script:
        
      Xvfb :0 -screen 0 640x480x8 &
           
    4. Finally, make sure your $DISPLAY environment variable is set correctly:
        
      export DISPLAY=:0
            

  3. You can also install Java 1.4 which does not require an X Server for AWT. However, at this point in the Java 1.4 development it will probably be more trouble than it is worth.
  4. I have also seen a post that the PJA toolkit, http://www.eteks.com/pja/en/, can also elminate the need for an underlying X server, though I haven't tested it myself.

Building Cocoon-based web applications

  1. When you build a web application, its deployment configuration must conform to the Java Servlet Specification 2.3 which looks like this:
    /			= root of the web application
    /WEB-INF
    /WEB-INF/classes/	= location of individual .class files
    /WEB-INF/lib/		= location of any libraries needed by the web app
    /WEB-INF/web.xml	= deployment descriptor
       
  2. Cocoon-based applications have three extra files, so their base deployment directory structure looks like this:
    /			= root of the web application
    /cocoon.xconf		= Cocoon configuration file
    /sitemap.xmap		= sitemap
    /WEB-INF
    /WEB-INF/classes/	= location of individual .class files
    /WEB-INF/lib/		= location of any libraries needed by the web app
    /WEB-INF/logkit.xconf	= logging configuration file
    /WEB-INF/web.xml	= deployment descriptor
       
  3. To incorporate Cocoon into your web application, you must already have download, unpacked and compiled Cocoon. Once compiled, the standard "cocoon" web application that comes with the distribution will be found at build/cocoon/webapp in the distribution directory. To build your own application, you'll need to edit and copy four files from this build directory to your new deployment directories. You will also need to copy certain libraries to this WEB-INF/lib directory of your deployment directory. The next sections address each of these in turn.
  4. web.xml: you will leave this file intact except for the preloading of the JDBC classes. You will need to make sure the right classes are in that section for whatever database you are using. Just follow the example given in the second section of this Guide.
  5. cocoon.xconf: you will need to edit datasources section as described above.
  6. sitemap.xmap: this will be edited the most. Of course, your biggest task will be adding entries for your own stuff. If you are interested in stripping down to the minimum, see the next section (forthcoming).
  7. logkit.xconf: copy this file unmodified
  8. libraries: these are the cocoon libraries (as of 2.0.x. Your list will be different). If you want to just load the minimum, see the section below (forthcoming).
    Tidy.jar
    avalon-excalibur-4.0.jar
    avalon-framework-4.0.jar
    batik-libs.jar
    bsf.jar
    cocoon-2.0rc1.jar
    dom2.jar
    fop-0_20_1-dev.jar
    hsqldb-1.61.jar
    jakarta-regexp-1.2.jar
    jimi-1.0.jar
    jstyle.jar
    junit.jar
    logkit-1.0b5.jar
    maybeupload.jar
    resolver.jar
    rhino.jar
    velocity-1.1.jar
    xalan-2.2.0-dev.jar
    xerces_1_4_3.jar
    xt.jar
       
  9. Finally, DON'T FORGET to create a logs subdirectory under WEB-INF for the Cocoon servlet to place its logs!
  10. For my web application development, I use ant and a development structure as described in the Tomcat documentation. For Cocoon-based apps, I put cocoon.xconf, sitemap.xmap and logkit.conf in the etc directory. I also put the Cocoon jars shown above in the lib directory. The "prepare" section in my build.xml looks like this:
      <target name="prepare">
        <mkdir dir="$"/>
        <copy todir="$">
          <fileset dir="web"/>
        </copy>
        <copy file="etc/cocoon.xconf" tofile="$/cocoon.xconf"/>
        <copy file="etc/sitemap.xmap" tofile="$/sitemap.xmap"/>
    
        <mkdir dir="$/WEB-INF"/>
        <copy file="etc/web.xml" tofile="$/WEB-INF/web.xml"/>
        <copy file="etc/logkit.xconf" tofile="$/WEB-INF/logkit.xconf"/>
        <mkdir dir="$/WEB-INF/classes"/>
    
        <mkdir dir="$/WEB-INF/logs"/>
    
        <mkdir dir="$/WEB-INF/lib"/>
        <copy todir="$/WEB-INF/lib">
          <fileset dir="lib"/>
        </copy>
        <mkdir dir="$"/>
       

Cocoon Performance

  1. You might find that the default memory assigned the Tomcat's JVM is not sufficient for Cocoon to transform large documents. If this is the case, one thing you can do is up the memory as follows. For Tomcat 3.2.x, you can put the following at the top of tomcat.sh:
    TOMCAT_OPTS=-mx512m
       
    For Windows users, that's:
    set TOMCAT_OPTS=-mx512m
       
    For Tomcat 4/5, you can put the following at the top of catalina.bat or catalina.sh:
    CATALINA_OPTS=-mx512m
       
    For Windows users, that's:
    set CATALINA_OPTS=-mx512m
       

    In either case, the integer value specifies the amount of memory you want the JVM to take, in megabytes; in these examples, I'm using 512 MB for Tomcat.


Back to Table of Contents