Tomcat classloader

I am using Tomcat for deploying my Java Web and Web Service applications for over 10 years now (yes, since the early 3.x versions). In the early days mostly for Struts applications and today for applications based on the Spring Framework (Spring MVC, Spring WebServices, Grails, …). In many of the projects I am consulting, we are using Tomcat in development and production environments too but the topic of this post has only been a discussion within the last few months, in one project.

The customer just started using Tomcat for some applications in production, instead of their default environment WebSphere. I think coming from WebSphere and doing a lot of J2EE applications with EJB is one of the reasons for their idea of putting a lot of dependencies into the library folders of the Tomcat, instead of putting them into the WAR file of the application.

In all of my other projects we are always putting all the required dependencies of an application into its WAR file, so that they are put into the WEB-INF/lib folder of the application. The only things I put in the Tomcat/lib folder are the JAR files for JDBC connections managed by tomcat. This allows me to use different versions of the dependencies in different applications deployed in the same Tomcat (e.g. Spring 2.5 and Spring 3 or JAX-WS 2.1 and JAX-WS 2.2).

Another benefit of the fat WAR file is, that the behavior of the application is more consistent. Putting it into different Tomcat installations in development, test or production environments has the same result.

This is also true for development: a new team member just has to download the default Tomcat distribution, fetch the application from the SCM system and start it up. All the required dependencies will be fetched via maven or ivy and put into the application. Requiring developers to put something into their local Tomcat installation (or even worse into their JDK) leads to different development environments across the team and issues that are very hard to track.

To support my arguments I did some research and found this article about Understanding The Tomcat Classpath from MuleSoft. MuleSoft provides a great Tomcat Enterprise Server named tcat with many management and monitoring features. In the article they discuss common problems and solutions for Tomcat classpath problems and provide tips and best practice advices. Their best practice advice is:

  • Avoid loading libraries and packages other than the standard ones distributed with Tomcat using the Commons Loader. This can cause compatibility errors. If you need to share a single library or package between multiple applications, create “shared/lib” and “shared/classes” directories and configure them under the Shared loader in
  • An exception to this rule is any common third party shared library, such as a JDBC driver. These should be placed directly into $CATALINA_HOME/lib
  • When possible, it is a good idea to use Apache Tomcat as recommended by its developers, as this represents conformance to the Servlet specification. If you’re finding that you have to configure classpath rather frequently, you may want to re-think your development process.

Additionally I posted a question on Stackoverflow about Third party libraries best practice in Tomcat. I think the answers pretty much support me in my opinion.

Hibernate schema update does not create database indices

In one of my Grails consulting projects we tried to define database indices via the static mapping element in the domain classes. A team member tried it an told me that this does not work so I digged a bit deeper to find out what the problem was.

I created a simple test project, configured hbm2ddl auto to update, like I am used to and let Grails create a MySQL database schema. It seemed lie my colleague was right, the defined indices were not created (using Grails 1.3.7). Doing some web research brought up this Stackoverflow posting suggesting that indices are only created when hbm2ddl auto was set to create (or create-drop) – which seemed to be the case.

In my opinion this had to be a bug in hibernate but some searches on the website brought up a statement about this in the official FAQ:

The setting doesn’t create indexes

SchemaUpdate is activated by this configuration setting. SchemaUpdate is not really very powerful and comes without any warranties. For example, it does not create any indexes automatically. Furthermore, SchemaUpdate is only useful in development, per definition (a production schema is never updated automatically). You don’t need indexes in development.

I do not agree with that, in our project it is necessary to have indices in development, otherwise we are not able to import the data we need for testing!

Luckily I found issue HHH-1012 in the Hibernate which states that this behavior was changed (fixed) in current hibernate versions – I tried it with Hibernate 3.6.4 and this version created indices even when the hbm2ddl setting is configured with update. Grails 1.4 will be using 3.6.x of Hibernate to so it seems like this issue will be resolved soon for our project.