Thursday, July 31, 2014

SpringOne 2GX 2014 is being held in Dallas, TX and I've been lucky enough to be selected to speak again this year.   I'll be co-presenting at the event with Stuart Williams, our presentation is Fastest Servlets in the West.  The session will talk about, you guessed it, performance of Servlet based applications running in Apache Tomcat.  We'll also talk about load testing, tuning the container and offer some tips for squeezing every bit of performance out of your app when it's running on Apache Tomcat.

The conference runs from Sept 8th to Sept 11th this year, with our talk scheduled for the first day at 12:45 PM.  If you're planning to come, register soon as early bird registration (saves you $150) ends, August 9th!

Tips on Migrating to Tomat 8 - Resources

One of the major changes from Tomcat 7 to Tomcat 8 was a refactoring with how Tomcat handles web application resources.  With Tomcat 7, there are features like aliases, VirtualLoader and VirtualDirContext that provide admins with a way to pull external resources into an app.  Unfortunately, each one of these features was implemented separately so to consolidate things and make them easier to maintain in Tomcat 8, all of these different implementations were combined into one resources framework which now handles all of that functionality.

Because of the consolidation and refactoring, several attributes from the Context configuration were removed and replaced with the Resources configuration.  This migration tip discusses how to switch from using common variations of the old Tomcat 7 configuration to the new Tomcat 8 Resources configuration.

Aliases

In Tomcat 7, the Context configuration tag has an attribute called aliases which can be used to provide a list of external locations from which Tomcat will load resources for the context.  There were a few reasons to use this, but one common reason was to use it to include static resources or configuration that an administrator wanted to place outside of a WAR file.

Here's an example configuration using aliases.
<Context aliases="/images=/var/www/images" />

Here's an example of the same configuration using Tomcat 8's Resources.
<Context>
  <Resources>
    <PostResources className="org.apache.catalina.webresources.DirResourceSet"
                   base="/var/www/images" webAppMount="/images" />
  </Resources>
</Context>


VirtualDirContext

The VirtualDirContext feature is similar to aliases but was targeted as a development feature.  The suggestion for using it is so that you do not have to deploy an entire WAR file.  Instead, you can point to the location of your static resources in your project and only copy, zip and deploy the code itself.

Here is an example of how this was used under Tomcat 7.  In this case, I'm using it to point to picture and movie assets that need to be included with the application.
<Context>
    <Resources className="org.apache.naming.resources.VirtualDirContext"
               extraResourcePaths="/pictures=/Users/theuser/mypictures,/movies=/Users/theuser/mymovies" />
</Context>
The same configuration under Tomcat 8 would look like this.
<Context>
  <Resources>
    <PostResources className="org.apache.catalina.webresources.DirResourceSet"
                   base="/Users/theuser/mypictures" webAppMount="/pictures" />
    <PostResources className="org.apache.catalina.webresources.DirResourceSet"
                   base="/Users/theuser/mymovies" webAppMount="/movies" />
  </Resources>
</Context>

It's also possible to use a PreResources tag, instead of the PostResources.  The difference would be that resources listed with a PostResources tag are checked after resources bundled in the web applications and resources with the PreResources tag are checked prior to resources bundled in the web application.  In other words, PreResources can be used to override a resource that is included with an application.

VirtualWebappLoader

The VirtualWebappLoader feature is used to add additional directories or JAR files onto the class path.  This is different from the previous two options because it allows you to add JAR files, classes or configuration to the class path and not just the file system.  Again, there are a few reasons why you might want to do this, one common reason was so that you could pull JAR files out from the WAR file to a centralized location.

Here's an example of how this was configured with Tomcat 7.
<Context>
  <Loader className="org.apache.catalina.loader.VirtualWebappLoader"
          virtualClasspath="/apps/shared/lib/*.jar,/apps/shared/classes" />
</Context>
Here's an example of how this is configured with Tomcat 8.
<Context>
  <Resources>
    <PostResources className="org.apache.catalina.webresources.DirResourceSet"
                   base="/apps/shared/lib" webAppMount="/WEB-INF/lib" />
    <PostResources className="org.apache.catalina.webresources.DirResourceSet"
                   base="/apps/shared/classes" webAppMount="/WEB-INF/classes" />
  </Resources>
</Context>
If you were using the searchExternalFirst attribute of the VirtualWebappLoader class, switching from using a PostResource tag to a PreResource tag should allow you to achieve the same behavior.

Additional Information

That covers some of the common configuration scenarios that have been changed due to the new Resources API.  For more information on this change, I would suggest the following resources.

Feel free to drop me a comment if I missed anything.