User Guide

To make use of this library you must run at least Java 1.6.

Notice
I have not tried this in any other major version except Apache Tomcat 6.0 but it should work in newer versions too. I would be glad to hear your success stories.

This site will guide you through the components of this library:

  1. CloseableResourceListener: Prevents memory leaks caused by left open resources during undeployment.
  2. LogbackContextNameListener: Makes Logback aware of a webapp's context name.
  3. EnhancedErrorReportValve: An alternative error report valve with several improvements over the original one.
  4. PropertiesRoleMappingListener: Provides a mapping from technical roles to application roles from a properties file.

Before using this library, make sure that the artifact is in the class path of your Tomcat instance, i.e., in $CATALINA_BASE/lib or $CATALINA_HOME/lib.

CloseableResourceListener

Ever wondered why your database runs out of connections or your JVM memory consumption is rising and rising when you undeploy web applications?
Here is the answer: Apache Tomcat does not close/free any resources during undeployment declared in a webapp's context.xml by default but relies on the garbage collector to clean them up. The rationale behind this is simple: Since you have declared the resource, you have to close it. For more details see the here.

This listener fixes this problem.

To make use of this listener you must declare it in your application. Open your app's context.xml and add:

<Context>
[…]
  <!-- Add this -->
  <Listener className="net.sf.michaelo.tomcat.extras.listeners.CloseableResourceListener" />
  <!-- Followed by your resources -->
  <!-- <Resource name="jdbc/oracle" type="javax.sql.DataSource" … /> -->
[…]
</Context>

Now all your resources will be cleanly closed during undeployment if they either are instances of Closeable or provide a zero arguments close method (reflection used).

LogbackContextNameListener

Logback is a great logging framework but how the heck can I instruct Logback to use my webapp's context name as my logfile name automagically? You can't…until now!

Open your app's context.xml and add:

<Context>
[…]
  <!-- Add this -->
  <Listener className="net.sf.michaelo.tomcat.extras.listeners.LogbackContextNameListener" />
[…]
</Context>

It will automagically add your webapp's context name as environment entry to your webapp's JNDI initial context. Now open your webapp's logback.xml and do:

<configuration>
  <!-- Add this -->
  <insertFromJNDI env-entry-name="java:comp/env/logback/contextName" as="contextName" />
  <contextName>${contextName}</contextName>

  <appender name="FILE"
    class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- Use here -->
    <file>${catalina.base}/logs/${CONTEXT_NAME}.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- or here -->
      <fileNamePattern>${catalina.base}/logs/${CONTEXT_NAME}.log.%d.gz</fileNamePattern>
      <maxHistory>30</maxHistory>
    </rollingPolicy>
    […]
  </appender>

  <root level="INFO">
    <appender-ref ref="FILE" />
  </root>
[…]
</configuration>

Logback will do the rest. If you do not like the name logback/contextName, simply provide your own by setting the name attribute on the Resource element.

EnhancedErrorReportValve

An alternative error report valve with several improvements over the original one. It includes, for instance, fixes for standards compliance or style and language improvements. See here for full details.

To enable the enhanced valve, open your server.xml, navigate to your <Host> element and add:

[…]
  <!-- Add this -->
  <Host […] errorReportValveClass="net.sf.michaelo.tomcat.extras.valves.EnhancedErrorReportValve">
    […]
  </Host>
[…]

Restart your Tomcat instance and enjoy.

PropertiesRoleMappingListener

Consider you cannot change the role names from your company's role store but would like to use readable role names in your app. This can be achieved with a proper mapping performed by this listener. For more details see the here.

To make use of this listener you must declare it in your application. Open your app's context.xml and add:

<Context>
[…]
  <!-- Add this -->
  <Listener className="net.sf.michaelo.tomcat.extras.listeners.PropertiesRoleMappingListener" />
  <!-- Followed by your realm -->
  <!-- <Realm … /> -->
[…]
</Context>

now add the appropriate role mapping file to WEB-INF/role-mapping.properties:

id-xyz = User
id-abc = Manager
id-foo = Admin

Make sure that your realm implementation actually queries the populated mapping and then you can user the new application roles in your web.xml and with request#isUserInRole().