Reading Time: 11 minutes

It's a very good thing that Tomcat is open source software. Because it is open, it enjoys broad stand-alone adoption, plus it has been incorporated as part of many other application server products, both commercial and open source. Why reinvent the wheel when Tomcat works great as a generic web container, and the source code is free? Many smart application server teams have chosen to embed Tomcat as their web container. They pull a copy of the Tomcat source code that they know works well, put it into their own source tree, and hook Tomcat's Ant build system into their own, and rebuild Tomcat as part of their project.

Sometimes, developers go overboard. They somehow end up with the notion that because they have the source code, and because it's open source, and because many Bothans died to bring us this information, that they should always rebuild the components from source code. This made a little sense back when the open source code was C code that either didn't run on Linux unless it was recompiled, or didn't run fast because the binaries were only compiled for i386 and not for i686. We got in the habit of recompiling from source just to get the platform specific binaries we needed. At the extreme, some of us got pulled so far into this thinking that they cannot be happy without recompiling literally everything specifically for the machine they're running it on, in an effort to squeeze out every last drop of hardware performance.

To me, this does not apply to Java software. Compiled Java bytecode is multi-platform, so there is no need for anyone to recompile it only to run it on another CPU model nor even on a completely different platform. And, it's the Java VM that optimizes it at runtime, so recompiling Java software for performance reasons is also out.

If the Apache Software Foundation (ASF) already provides an official binary of each Tomcat release, then why would developers or sysadmins want to recompile Tomcat from source when they're not developing Tomcat's code?  Tomcat binaries are compact at around 6 MB (for Tomcat 6.0), but the source code is nearly ten times that size at 55 MB, and that source is organized into several sub-projects that are each built separately. Currently, Tomcat 6.0's source tree contains 1257 Java source files — it is a significantly large codebase. And, if we're not careful, there are things that can go wrong when we compile it.

Here are some gotchas:

Most people will pull the Tomcat trunk source tree instead of a tagged release's source. The first link that the official Tomcat web documentation gives is this Subversion URL:

http://svn.apache.org/repos/asf/tomcat/tc6.0.x/

. . . which causes many people to pull that path, only to find that they're receiving all branches, tags, and trunk for Tomcat 6, which is a huge set they don't need. Then, on the next try, many will choose to download the trunk source, which is relatively stable, but under development and not necessarily tested. If you download and compile the trunk source tree, it may not even build because new changes are being made to that very copy in Subversion. If it happens to build, you got lucky, but the resulting binaries are probably unstable because you have not pulled and built a stable release tag's source tree.

In the source code, the BUILDING.txt file says:

“Checkout the source using SVN, selecting the desired version or branch (current development source is at http://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk/), or unpack the source package. The location where the source has been placed will be referred as ${tomcat.source}.”

For those who are patient, and take the time to read the BUILDING.txt file, they'll at least see that it is suggested you pull a “version or branch,” but that doesn't specifically suggest checking out a release tag's source. Checking out any source tree from the ASF Subversion repository other than a release tag is significantly more likely to result in runtime bugs that are only discovered down the road in production.

Instead, these docs should suggest pulling a tag, such as:

http://svn.apache.org/repos/asf/tomcat/tc6.0.x/tags/TOMCAT_6_0_20

. . . unless a wants to work on the latest (unstable) code of Tomcat.

Then, when building the source, you must use the ant download target to download all of the dependent JAR files and other binaries. You do that like this:

$ mkdir lib
$ cp build.properties.default build.properties

Edit build.properties and change base.path to $PWD/lib, and then enter the following command:
$ export ANT_OPTS="-Xms1024M -Xmx1024M"
$ ant download

[ant downloads lots of binaries]

Doing that should work fine, and then Tomcat may build when that's done. The build.properties file is there to configure how Ant builds Tomcat. If you read through this file, you'll notice that it doesn't just contain relatively trivial details like the file system path where the dependencies are downloaded, but it also contains important settings such as which versions of the dependency JARs Tomcat compiles against.

By convention we copy the default properties file to the name build.properties as an easy way to customize the build settings while stepping out of the way of Subversion's version control of the default settings. The fact that we're copying the default properties file to another filename that is not controlled by Subversion means that upon the next Subversion update, the build.properties file does not get updated. Instead, the build.properties.default file gets the update. Why is this significant? Because if the Tomcat committers change the dependencies, your slightly customized build.properties file won't know anything about that change, and the updated Tomcat source code may make the assumption that you're building against a different set of JARs. The first time you pull the source and build it, this probably isn't a problem. But if you come back later to this source tree and perform a Subversion update and rebuild, your resulting Tomcat binary can have runtime problems that range from critical to subtle. Often these problems manifest themselves as strange web application behaviour. To prevent that situation, you would have to throw away your build.properties file every time you do a Subversion update, re-copy build.properties.default, and re-edit before rebuilding.

These are only some examples of problems that can be caused by recompiling Tomcat from source as opposed to using the official ASF release binaries. For developers who are improving Tomcat's code, or who need to build some of the Tomcat extras components (a rather rare situation), of course you'll need to be able to recompile Tomcat, and in that case I hope this helps you avoid some problems.  For everyone else: Tomcat is open source software, and you have everything you need to rebuild it if you'd like to, but I encourage you to use the official, well-tested ASF release binaries.

latest report
Learn why we are the Leaders in management and