March 31, 2005

Running Cocoon Under SecurityManager

Here are few tips on how it's possible to run Apache Cocoon under the SecurityManager. I'm assuming here that Cocoon is deployed into the Apache Tomcat 5 application server which is started with:

  catalina start -security

So, in order to make Cocoon run in this environment, follow these steps:

  • Make sure your Cocoon is compiled from SVN revision 159598 or later. This means Cocoon 2.1.8 release or later.
  • Make sure excalibur URLSource class is SVN revision 159586 or later.
  • Edit WEB-INF/cocoon.xconf file to replace EHCache with default store implementation:
    <store logger="core.store"
           class="org.apache.cocoon.components.store.impl.DefaultStore">
      <parameter name="maxobjects" value="1000"/>
      <parameter name="use-persistent-cache" value="false"/>
    </store>
    
    (EHCache tries to set java.tmp.dir - that shouldn't be allowed.)
  • Edit WEB-INF/logkit.xconf and point to directory with write access (I'll use in this example Cocoon working directory):
    <filename>${work-directory}/logs/cocoon.log</filename>
    
  • And finally, edit $CATALINA_HOME/conf/catalina.policy. Add following entries to the last grant block:
    // File Encoding Property
    permission java.util.PropertyPermission "file.property", "read";
    
    // XML SAX and DOM Parsers Configuration Properties
    permission java.util.PropertyPermission "org.xml.sax.driver", "read";
    permission java.util.PropertyPermission "org.apache.cocoon.components.parser.Parser", "read";
    permission java.util.PropertyPermission "org.apache.excalibur.xml.sax.SAXParser", "read";
    permission java.util.PropertyPermission "javax.xml.parsers.SAXParserFactory", "read";
    permission java.util.PropertyPermission "javax.xml.parsers.DocumentBuilderFactory", "read";
    
    // XML Catalog Properties
    permission java.util.PropertyPermission "xml.catalog.ignoreMissing", "read";
    permission java.util.PropertyPermission "xml.catalog.files", "read";
    permission java.util.PropertyPermission "xml.catalog.staticCatalog", "read";
    permission java.util.PropertyPermission "xml.catalog.className", "read";
    permission java.util.PropertyPermission "xml.catalog.prefer", "read";
    permission java.util.PropertyPermission "user.dir", "read";
    
    // Cocoon ClassLoader
    permission java.lang.RuntimePermission "createClassLoader";
    

With the above config, you get nicely working Cocoon core with one caveat: there is some class loading issue with flow, even if you give it all permissions it needs. Weird. If you have luck with it, let me know.

Posted by Vadim at March 31, 2005 10:46 AM
Comments

I tried your instructions with both Tomcat 5.0.28 and 4.1.13. Thanks to your tips my Cocoon web application finally starts up without a problem (permissions that were not explicitly granted are logged with "Caught a SecurityException reading the system property [...]").

However, I can't even access a page that is generated with a simple XSL transformation.

Upon the first request I get the following stack trace (hopefully irrelevant parts omitted):

StandardWrapperValve[Cocoon]: Servlet.service() for servlet Cocoon threw exception
java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:141)
at org.apache.xalan.serialize.SerializerFactory.getSerializer(SerializerFactory.java:131)
at org.apache.xalan.transformer.TransformerIdentityImpl.createResultContentHandler(TransformerIdentityImpl.java:232)
at org.apache.xalan.transformer.TransformerIdentityImpl.startDocument(TransformerIdentityImpl.java:869)
[...]
Caused by: java.lang.RuntimeException: The resource [ XMLEntities.res ] could not load: java.net.MalformedURLException: no protocol: XMLEntities.res
XMLEntities.res java.net.MalformedURLException: no protocol: XMLEntities.res
at org.apache.xalan.serialize.CharInfo.(CharInfo.java:241)
at org.apache.xalan.serialize.SerializerToXML.(SerializerToXML.java:292)
... 67 more

Upon further requests, the stack trace is just as following:

StandardWrapperValve[Cocoon]: Servlet.service() for servlet Cocoon threw exception
java.lang.NoClassDefFoundError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:141)
at org.apache.xalan.serialize.SerializerFactory.getSerializer(SerializerFactory.java:131)
at org.apache.xalan.transformer.TransformerIdentityImpl.createResultContentHandler(TransformerIdentityImpl.java:232)
at org.apache.xalan.transformer.TransformerIdentityImpl.startDocument(TransformerIdentityImpl.java:869)
[...]

I don't use flow scripts. Any idea what the cause the NoClassDefFoundErrors could be?


Posted by: Thomas Zumbrunn at April 3, 2005 6:33 PM

Thomas,

From the message "The resource [ XMLEntities.res ] could not load: java.net.MalformedURLException: no protocol: XMLEntities.res" I can only tell that this is either problem with entity resolver, or with Xalan. Try out default Cocoon with samples - xslt transformation there works. See what's different in your environment, what configuration differs, check entity resolver configuration, do other troubleshooting. Good luck! :-)

Posted by: Vadim Gritsenko at April 3, 2005 10:06 PM

Actually, trying out default Cocoon with samples was the first thing I did. There I also got strange java.lang.NoClassDefFoundErrors. That's why I tried my own stripped down Cocoon webapp.

However, after fiddling around for hours and hours I found the mistake: I didn't update the xerces, xalan and xml-api JARs of my Tomcat installation (as described here).

Ouch...

Posted by: Thomas Zumbrunn at April 4, 2005 3:49 PM

I meant to write "as described at http://cocoon.apache.org/2.1/installing/" (didn't know that one cannot use HTML tags).

Posted by: Thomas Zumbrunn at April 4, 2005 3:53 PM