Frequently Asked Questions
http://xml.apache.org/http://www.apache.org/http://www.w3.org/

Index
License
Download

Documentation
Introduction
Installing
User Guide
Dev Guide
Tutorial
FAQs
ToC

Status
Changes
Todo

Community
Hall of Fame
Contributing
Mail Lists
Mail Archives

Project
Bug Database
Code Repository
Dev Snapshots

Hosting
Live Sites
Cocoon Hosting

Links
Cocoon Links
XML Links

Cocoon 1.x
Old Generation

Questions
Answers
Why does nothing happen when I access 'http://localhost/cocoon/'?

You might want to check a few things:

  • is your server listening to port 80? if not, you have to call the right port like in 'http://localhost:8080/cocoon/'. Note that Apache Tomcat binds by default to port 8080, NOT 80.
  • did your servlet engine install the WAR file? you can check by making sure the WAR file was unpacked or connecting to the administration tools of your servlet engine.
  • did you restart the servlet engine? if not, do it.
Why does Cocoon take so long to start?

Cocoon compiles sitemaps into java classes to increase runtime performance, this is done only at startup and only if the sitemap file is modified, for all the other requests the compiled sitemap is executed. See question #7 for information on how to pre-compile the sitemap and the XSP's.

Why is cocoon.war so big?

Cocoon.war includes all the libraries that it requires to run. They are several megabytes of Java classes and it also includes the JDK javac compiler which must be present in the war file to allow page compilation without classloading problems.

I get a java.lang.VerifyError when accessing 'http://localhost/cocoon/'. What's wrong?

Cocoon requires a JAXP 1.1 compliant parser. Some servlet engines (like Tomcat 3.2.1) use older xml parsers. You have to replace the xml parser with a newer one (e.g. the Xerces 1.3.0 or newer).

For Tomcat 3.2.1 simply remove the jaxp.jar and the parser.jar from the tomcat/lib directory and copy the xerces.jar to this directory and rename it to parser.jar. Before you restart Tomcat make sure to remove the tomcat/work directory beforehand.

Cocoon still won't start, this time I get javax.xml.transform.TransformerConfigurationException: Namespace not supported by SAXParser in the Cocoon log file.

This is a classloader issue with Tomcat and some other Servlet Engines. Basically it means that the Xerces library included with Cocoon is not being found. The solution is to place the Xerces library first in the classpath.

Cocoon won't start and I get a "java.lang.NoSuchMethodError: org.apache.log.LogKit: method createLogger(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/apache/log/Logger; not found" in my Servlet Container's log.

You have an old set of libraries installed. Copy the correct libraries from the distribution.

Even better, if you build Cocoon with "build -Dinclude.webapp.libs webapp" then Cocoon will create a complete WAR file for you with all necessary libraries.

Windows 95/98 tells me that I don't have enough environment- memory?

This is another neat feature from DOS- times. To increase environment-space add the following line to your config.sys (and restart): shell=c:\command.com /E:4096 /P

I'm still stuck, what do I do?

Contact the Cocoon Users mail list (cocoon-users@xml.apache.org). Please, do not contact developers directly for help since the user list are normally much more responsive and users normally have more experience in solving installation problems than developers do.

Cocoon has a log file that is stored in the context where you placed Cocoon. It is located in '{cocoon}/WEB-INF/logs/cocoon/log' where {cocoon} is the context where Cocoon is installed. Many times, the information contained in that file will help others help you.

When I try to use the Connection pooling code, I get the following exception: "Could not get the datasource java.sql.SQLException: You cannot get a Poolable before the pool is initialized". What's going on?

The most common reason for this exception is that the driver was not loaded. Cocoon uses an initial parameter in the "web.xml" file to automatically load classes on startup. This way, the class is loaded only once and the server's time is spent doing more productive things. Make sure the following entry is in your "web.xml" file:

<init-param>
 <param-name>load-class</param-name>
 <param-value>
   <!-- comma or whitespace separated list of fully
     qualified class names to load on startup.
   -->
   oracle.jdbc.driver.OracleDriver
 </param-value>
</init-param>

If the class is loaded correctly, and you are still getting this error, then there is probably an error in your connection information. The SQLException above is thrown when there are no open connections to the database.

What are the steps to pre-compile the sitemap and XSP's?
  • Set the auto-reload to false in your sitemap.xmap as follows:
<parameter name="auto-reload" value="false"/>
  • Use "-Dbuild.precompile=true" in your build command line when you are building your WAR file.
How do i setup my own .roles file?

In cocoon.xconf you can specify your my.roles file as follows:

   ...
   <cocoon version="2.0" user-roles="WEB-INF/my.roles">
   ...

And create a new file my.roles in WEB-INF directory with

<?xml version="1.0"?>
<role-list>
  <role name="org.apache.cocoon.components.jsp.JSPEngine"
        shorthand="jsp-engine"
        default-class="org.apache.cocoon.components.jsp.JSPEngineImplWLS"/>   
</role-list>
I get an error saying that "The sitemap handler's sitemap is not available". What can I do?

Check the Cocoon error log under WEB-INF/logs/error.log: the error you are seeing is actually a consequence of something that went wrong in the Cocoon process. The root cause of the exception is usually reported there.

I don't want to hand edit the sitemap. Are there any tools?

Try this by Bruno Dumon.

How do I create some content which isn't directly visible to everyone?

Put the content in an internal pipeline...

<map:pipelines>
 <map:pipeline internal-only="true">
   <map:match pattern="int">
     <map:generate src="docs/description.xml"/>
     <map:serialize type="xml"/>
   </map:match>
 </map:pipeline>
 <map:pipeline>
   <map:match pattern="desc.html">
     <map:generate src="cocoon:/int"/>
     <map:transform src="stylesheets/description2html.xsl"/>
     <map:serialize type="html"/>
   </map:match>
 </map:pipeline>
</map:pipelines>
How can I concatenate two xml files?
<map:pipelines>
 <map:pipeline internal-only="true">
   <map:match pattern="one">
     <map:generate src="docs/one.xml"/>
     <map:serialize type="xml"/>
   </map:match>
   <map:match pattern="two">
     <map:generate src="docs/two.xml"/>
     <map:serialize type="xml"/>
   </map:match>
 </map:pipeline>
 <map:pipeline>
   <map:match pattern="desc.html">
     <map:aggregate element="newRootElement">
       <map:part src="cocoon:/one" element="firstXMLfile"/>
       <map:part src="cocoon:/two" element="secondXMLfile"/>
     </map:aggregate>
     <map:transform src="stylesheets/merge2html.xsl"/>
     <map:serialize type="html"/>
   </map:match>
 </map:pipeline>
</map:pipelines>

Where the element attribute names are replaced with something more meaningful! Note that the map:part element attributes can be left off, which results in the two parts being placed one immediately after the other.

I want to use the XXX matcher/serializer/selecter/etc but there's no examples :(

If you've checked the sample webapps which come with Cocoon, and you've looked in the documentation, then check both the user and dev archives. If it hasn't been resolved before first email the user group and, after a reasonable (ie 1 or 2 days) length of time (remember not everyone lives in your timezone) email the dev group.

Please don't cross-post to both the user and dev groups - very few people like getting bombarded!

Oh, and once you do get it working - how about documenting it and contributing it back to the group?

The sql samples don't run.

The sql samples are working when deploing the war file using the build system:

./build.sh \
   -Dinclude.webapp.libs=yes \
   -Dinstall.war=path/to/tomcat/webapps install
This command will take care of the path inside the configuration file to the database resources.

I've been able to run the database samples, but they don't run anymore.

This happens when the servlet engine has been stopped abruptly (e.g. with ctrl-C).

Hsqldb - the database used by C2 samples - is a single-process engine that locks the database by setting the "modified" entry in "WEB-INF/db/cocoondb.properties" to the value "yes" while some JDBC connections exist.

With connection pooling, there's always some connections opened, and they're not closed properly when you stop abruptly the servlet engine, so the database stays in locked state and connections are refused at the next server startup.

To unlock the database, change manually "modified" to "no" in the "cocoondb.properties" before restarting the server.

When I add an action to a pipeline Cocoon returns an error.

Before the action was added to the pipeline it worked fine. After the change Cocoon seems not to find the file specified in the variable that is returned by the matcher.

<map:match pattern="*">
  <map:act type="validate-session">
    <map:generate type="serverpages" src="{../1}.xsp"/>
  </map:act>
  <map:serialize/>
</map:match>

Please note in the above example the "../1".

Map objects returned from matchers, actions etc. are organised hierarchically. Therefore they are not replaced by new ones but older ones are still accessible through a path expression. Here "../1" references key ("variable") "1" in the next to last Map.

How could I have my Cocoon app in an URI other than <you-server>/cocoon/<my-app>?

Note This entry refers only to an Apache + Tomcat + Cocoon configuration, and was tested under: Windows NT 4.0 + Apache 1.3.14 + Tomcat 3.2 + Cocoon 2.0b1.

Test whether Tomcat passes everything under the /cocoon context to Cocoon. This may be tested by pointing your browser at <your-server>:8080/cocoon/xsp/simple, if a text page named "A simple XSP page", everything's fine.

Now, suppose:

  1. you have a Cocoon application named "foo" which works fine when called with <your-server>:8080/cocoon/foo
  2. you want the "foo" app to be called from <your-server>:8080/foo instead.

The idea is just to redirect the desidered URI (foo) to the one within the cocoon context (cocoon/foo).

Since this has to be done before the URI is processed by Tomcat, it is just natural to use Apache for this. And, of course the user should not notice the redirection.

Apache has an handy feature called mod_rewrite which does just this: URI rewriting (see the "URL Rewriting Guide" in the Apache user's guide for details).

First of all, you should instruct Apache to load the mod_rewrite, hence, you should add (on a Windows system) this line to the httpf.conf:

LoadModule rewrite_module modules/ApacheModuleRewrite.dll

(by the way, most probably, this line is already on the httpd.conf, you just have to un-comment it).

Add this line to httpd.conf in order to activate mod_rewrite:

RewriteEngine On

It is highly recommended to use the logging option of mod_rewrite, in order to check the correctness of the URI rewriting; just add this lines to the httpd.conf:

RewriteLog "C:/logs/rewrite.log"
RewriteLogLevel 9

The first line tells Apache to put the URI rewriting log in the c:\logs\rewrite.log file (which happens to be on a Windows system, of course). The second one tells Apache to record everything mod_rewrite does, if you don't want to log anything, just set the RewriteLogLevel to 0.

Now, it's time to do the URI rewriting trick:

RewriteRule foo/(.*) /cocoon/foo/$1 [PT]

This line instructs Apache to redirect everything under "foo" to "cocoon/foo" and passes it on to other processing ("[PT]" option), like mod_alias.

Now, just restart Apache and point your browser to:

<your-server>:8080/foo/<something>...

it should work just fine.

How could I have my Cocoon app in a directory other than $TOMCAT_HOME/webapps/cocoon/<my-app>?

NoteThis entry refers only to an Apache + Tomcat + Cocoon configuration, and was tested under: Windows NT 4.0 + Apache 1.3.14 + Tomcat 3.2 + Cocoon 2.0b1.

Let's suppose the following:

  1. you have an application called "foo" which works perfectly when located under the %TOMCAT_HOME%\webapps\cocoon\foo directory.
  2. you want it to be located under the "c:\foo" directory instead

This could be done pretty easily twisting a little bit the sitemap. The idea is to mount the sub-sitemap of the "foo" application on a specific location on the file system, rather than under the deafult cocoon context.

Here's the sitemap.xmap fragment used to do this:

<map:pipeline>
 <map:match pattern="foo/**">
  <map:mount uri-prefix="foo" src="file:///c:/foo/"/>
 </map:match>
</map:pipeline>

The "file:" type of source forces Cocoon to search the sub-sitemap under the specified directory (which happens to be "c:\foo", since this is a Windows system).

Now, you just need to copy everything which was under the webapps/cocoon/foo directory to the /foo directory, and it should work graciously.

How do i integrate Apache Server and Cocoon?

You need to use mod_jk. Add the following line to %APACHE_HOME%\conf\httpd.conf

JkMount /cocoon/* ajp12

along with other directives that are already listed in mod_jk.conf-auto in the tomcat/conf directory. The the above directives can be added at the end of httpd.conf.

How do i hide "cocoon" in the URL's once i integrate using mod_jk as shown above?

Basically to use http://your.server.org/Foo/welcome (as an example) instead of http://your.server.org/cocoon/Foo/welcome. You need the following two modifications:

Step #1: Add the following lies to to httpd.conf.

RewriteEngine On
RewriteLog "/var/log/rewrite.log"
RewriteLogLevel 0
RewriteRule ^/Foo /cocoon/Foo/ [R]
RewriteRule ^/Foo(.*) /cocoon/Foo$1 [R]

The file rewrite.log does not have to be located in /var/log. For instance, under Windows NT other locations may be appropriate. The RewriteLogLevel should be set 3 for debug purposes. The third line is essentially a redirect, so that Foo becomee /cocoon/Foo/ with the trailing /, without it the request would not map onto

<map:match pattern="">
   <map:redirect-to uri="welcome" />
</map:match>

when you I request http://your.server.org/Foo. Finally, the last RewriteRule could depend on the local settings. The original suggestion by Luca was a single line entry (that replaces both RewriteRules above) according to:

RewriteRule Foo/(.*) /cocoon/Foo/$1 [PT]

Note This did not work in my case (Slackware Linux with Apache1.3, tomcat3.2.2, Cocoon). Again, these RewriteRules may vary somewhat depending on the local settings. You may have to experiment a bit.

Step #2: Add to the sitemap.xmap in the cocoon directory.

<map:pipeline>
    <map:match pattern="Foo/**">
      <map:mount uri-prefix="Fru" src="/www/Foo/"
                 check-reload="yes" reload-method="synchron"/>
    </map:match>
</map:pipeline>

Here, /www/Foo is a some directory on the local file system where the xml, xsp, .., files of the application Foo live.

Note The src attribute may have to include "file://"

How can I run Cocoon without X11. Why is a Display needed?

An Xserver is needed due to the batik library fop uses. batik uses java's graphics code, which in turn requires the Xserver. If you don't have an xserver on your system, and can't set the DISPLAY variable to one, then try out xvfb. xvfb gives you an 'in-memory' xserver, which doesn't require any display hardware to run.

$> Xvfb :1 -screen 0 800x600x8 &
$> export DISPLAY=:1
$> $TOMCAT_HOME/bin/startup.sh -f server.xml

Another solution is to use PJA library. Read 'Linux/Headless/Batik' section in the Cocoon installation guide.

How do i debug Cocoon using JDK1.3+?

With JDK1.3, you can set the TOMCAT_OPTS (for Tomcat 3.X) or CATALINA_OPTS (for Tomcat 4.X) as shown below (on Win2K) and then attach the debugger to localhost:8000 using "jdb -attach myhost:8000" More information can be found at JPDA - Connection and Invocation Details.

set TOMCAT_OPTS=-classic -Xdebug -Xnoagent -Djava.compiler=NONE
    -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 

Note This method is supposed to work under JBuilder4.0 as well.

Where do i setup LogKit in Cocoon?

1. {cocoon}/WEB-INF/logkit.xconf:

Please refer to the Avalon Excalibur Documentation: Avalon Excalibur LogKit Management

2. {cocoon}/WEB-INF/web.xml:

Here you can change following paramters:

  • logkit-config: This parameter indicates the configuration file of the LogKit management
  • servlet-logger: This parameter indicates the category id of the logger from the LogKit configuration used by the CocoonServlet.
  • cocoon-logger: This parameter indicates the category id of the logger from the LogKit management configuration for the Cocoon engine. This logger is used for all components described in the cocoon.xconf and sitemap.xmap file not having specified a logger with the logger="..." attribute in the component configuration file.
  • log-level: This parameter indicates the log level to use throughout startup of the system. As soon as the logkit.xconf the setting of the logkit.xconf configuration is used instead! Only for startup and if the logkit.xconf is not readable/available this log level is of importance.

NoteSee inline comments in these files for further information!

How do i tell Cocoon to stop adding carriage-returns during xsl transformation ?

The short answer is that this is not a Cocoon issue - you need to read up on XSLT usage. Please see other resources for XSLT (specifically the XSL FAQ and discussion lists).

The full answer is that you need to use the XSLT function normalize-space() whenever you want to rely on the content of an xml element.

For example, if your application is producing some Javascript code in your HTML output, then you might mistakenly try to use the following construct in your XSL stylesheet ...

alert('<xsl:value-of select="message"/>');

which will produce ...

alert('
messageValue
');

That will cause js errors. The reason is that there are line-endings in the content of your "message" element. So you need to do this ...

alert('<xsl:value-of select="normalize-space(message)"/>');

Note that there are many more issues about whitepace handling. Please refer to the relevant XSLT resources, rather than cluttering the Cocoon discussion lists.

I changed the sitemap, but my changes don't show in the browser, do I need to re-start the servlet container?

Cocoon lets you decide whether it has to poll for sitemap changes (with its associated performance penalty) or not, and, if it has to, Cocoon lets you decide whether the re-compile has to happen in the background or in the foreground.

If you look at the cocoon.xconf file, you'll notice this element:

<sitemap file="sitemap.xmap"
         reload-method="asynchron"
         check-reload="yes"/>

Which means:

  • The check-reload attribute determines if the sitemap is reloaded on change. Set to "no", the sitemap is generated once at startup. Set to "yes", the sitemap is regenerated if it changes.
  • The reload-method specifies the method for the regeneration:
    1. asynchron: If the sitemap changes, the sitemap is regenerated at the next request in the background and the incoming request is served with the old sitemap. All subsequent requests are served with the old sitemap until the regeneration in the background has finished.
    2. synchron: If the sitemap changes, the sitemap is regenerated at the next request. When the regeneration is finished, the request (and all subsequent ones) is served with the new sitemap.
For development environment, set the reload-method to synchron and the check-reload to yes. For production environment, it is advisable to set the reload-method to asynchron and for more safety the check-reload to no.

In a nuthsell: By default reload is "asynchron" which means:

  1. Change sitemap
  2. Hit reload
  3. Wait while CPU goes up to 100% and back down to 0%
  4. Hit reload
  5. Voila - new sitemap is used! :)
Hence: you don't need to restart the servlet container.

For sub-sitemaps, this issue is defined in the mounting element:

<map:mount uri-prefix="foo" src="file:///c:/foo/"
           check-reload="yes"
           reload-method="synchron"/>
With these settings Cocoon will react to any changes in the sub-sitemap, without even hitting the reload button twice :)

Moreover, using sub-sitemaps is a good idea, since it reduces compilation time (if you change just a sub-sitemap the main sitemap and the others sub-sitemaps won't be compiled) and lead to greater degree of modularity.

Copyright © 1999-2002 The Apache Software Foundation. All Rights Reserved.