The Tomcat startup scripts are found within your project under the bin folder. Each script is available either as a Windows batch file (.bat), or as a Unix shell script (.sh). The behavior of either variant is very similar, and so I’ll focus on their general structure and responsibilities, rather than on any operating system differences. However, it is to be noted that the Unix scripts are often more readable than the Windows batch files.
In the following text, the specific extension has been omitted, and either .bat or .sh should be substituted as appropriate. Furthermore, while the Windows file separator ” has been used, it can be substituted with a ‘/’ as appropriate.
The overall structure of the scripts is as shown—you will most often invoke the startup script.
Note that the shutdown script has a similar call structure. However, given its simplicity, it lends itself to fairly easy investigation, and so I leave it as an exercise for the reader.
Both startup and shutdown are simple convenience wrappers for invoking the catalina script. For example, invoking startup.bat with no command line arguments calls catalina.bat with an argument of start. On the other hand, running shutdown.bat calls catalina.bat with a command line argument of stop. Any additional command line arguments that you pass to either of these scripts are passed right along to catalina.bat.
The startup script has the following three main goals:
- If the CATALINA_HOME environment variable has not been set, it is set to the Tomcat installation’s root folder. The Unix variant defers this action to the catalina script.
- It looks for the catalina script within the CATALINA_HOMEbin folder. The Unix variant looks for it in the same folder as the startup script. If the catalina script cannot be located, we cannot proceed, and the script aborts.
- It invokes the catalina script with the command line argument start followed by any other arguments supplied to the startup script.
The catalina script is the actual workhorse in this process. Its tasks can be broadly grouped into two categories. First, it must ensure that all the environment variables needed for it to function have been set up correctly, and second it must execute the main class file with the appropriate options.
Setting up the environment
In this step, the catalina script sets the CATALINA_HOME, CATALINA_BASE, and CATALINA_TMPDIR environment variables, sets variables to point to various Java executables, and updates the CLASSPATH variable to limit the repositories scanned by the System class loader.
- It ensures that the CATALINA_HOME environment variable is set appropriately. This is necessary because catalina can be called independently of the startup script.
- Next, it calls the setenv script to give you a chance to set any installation-specific environment variables that affect the processing of this script. This includes variables that set the path of your JDK or JRE installation, any Java runtime options that need to be used, and so on. If CATALINA_BASE is set, then the CATALINA_BASEbinsetenv script is called. Else, the version under CATALINA_HOME is used.
- If the CATALINA_HOMEbinsetclasspath does not exist, processing aborts. Else, the BASEDIR environment variable is set to CATALINA_HOME and the setclasspath script is invoked. This script performs the following activities:
- It verifies that either a JDK or a JRE is available. If both the JAVA_HOME and JRE_HOME environment variables are not set, it aborts processing after warning the user.
- If we are running Tomcat in debug mode, that is, if ‘–debug’ has been specified as a command line argument, it verifies that a JDK (and not just a JRE) is available.
- If the JAVA_ENDORSED_DIRS environment variable is not set, it is defaulted to BASEDIRendorsed. This variable is fed to the JVM as the value of the –Djava.endorsed.java.dirs system property.
- The CLASSPATH is then truncated to point at just JAVA_HOMElibtools.jar. This is a key aspect of the startup process, as it ensures that any CLASSPATH set in your environment is now overridden.
Note that tools.jar contains the classes needed to compile and run Java programs, and to support tools such as Javadoc and native2ascii. For instance, the class com.sun.tools.javac.main.Main that is found in tools.jar represents the javac compiler. A Java program could dynamically create a Java class file and then compile it using an instance of this compiler class.
- Finally, variables are set to point to various Java executables, such as java, javaw (identical to java, but without an associated console window), jdb (the Java debugger), and javac (the Java compiler). These are referred to using the _RUNJAVA, _RUNJAVAW, _RUNJDB, and _RUNJAVAC environment variables respectively.
- The CLASSPATH is updated to also include CATALINA_HOMEbinbootstrap.jar, which contains the classes that are needed by Tomcat during the startup process. In particular, this includes the org.apache.catalina.startup.Bootstrap class. Note that including bootstrap.jar on the CLASSPATH also automatically includes commons-daemon.jar, tomcat-juli.jar, and tomcat-coyote.jar because the manifest file of bootstrap.jar lists these dependencies in its Class-Path attribute.
- If the JSSE_HOME environment variable is set, additional Java Secure Sockets Extension JARs are also appended to the CLASSPATH.
Secure Sockets Layer (SSL) is a technology that allows clients and servers to communicate over a secured connection where all data transmissions are encrypted by the sender. SSL also allows clients and servers to determine whether the other party is indeed who they say they are, using certificates. The JSSE API allows Java programs to create and use SSL connections.
Though this API began life as a standalone extension, the JSSE classes have been integrated into the JDK since Java 1.4.
- If the CATALINA_BASE variable is not set, it is defaulted to CATALINA_HOME. Similarly, if the Tomcat work directory location, CATALINA_TMPDIR is not specified, then it is set to CATALINA_BASEtemp. Finally, if the file CATALINA_BASEconflogging.properties exists, then additional logging related system properties are appended to the JAVA_OPTS environment variable.
All the CLASSPATH machinations described above have effectively limited the repository locations monitored by the System class loader. This is the class loader responsible for finding classes located on the CLASSPATH.
At this point, our execution environment has largely been validated and configured.
The script notifies the user of the current execution configuration by writing out the paths for CATALINA_BASE, CATALINA_HOME, and the CATALINA_TMPDIR to the console. If we are starting up Tomcat in debug mode, then the JAVA_HOME variable is also written, else the JRE_HOME is emitted instead.
These are the lines that we’ve grown accustomed to seeing when starting up Tomcat.
Using CATALINA_BASE: C:tomcatTOMCAT_6_0_20outputbuild
Using CATALINA_HOME: C:tomcatTOMCAT_6_0_20outputbuild
Using CATALINA_TMPDIR: C:tomcatTOMCAT_6_0_20outputbuildtemp
Using JRE_HOME: C:javajdk1.6.0_14
With all this housekeeping done, the script is now ready to actually start the Tomcat instance.
Executing the requested command
This is where the actual action begins. This script can be invoked with the following commands:
- debug [-security], which is used to start Catalina in a debugger
- jpda start, which is used to start Catalina under a JPDA debugger
- run [-security], which is used to start Catalina in the current window
- start [-security], which starts Catalina in a separate window
- stop, which is used to stop Catalina
- version, which prints the version of Tomcat
The use of a security manager, as determined by the optional –security argument, is out of scope for this article.
The easiest way to understand this part of catalina.bat is to deconstruct the command line that is executed to start up the Tomcat instance.
This command takes this general form (all in one line):
- _EXECJAVA is the executable that should be used to execute our main class. This defaults to the Java application launcher, _RUNJAVA. However, if debug was supplied as a command-line argument to the script, this is set to _RUNJDB instead.
- MAINCLASS is set to org.apache.catalina.startup.Bootstrap
- ACTION defaults to start, but is set to stop if the Tomcat instance is being stopped.
- CMD_LINE_ARGS are any arguments specified on the command line that follow the arguments that are consumed by catalina.
- SECURITY_POLICY_FILE defaults to CATALINA_BASEconfcatalina.policy.
- JAVA_OPTS and CATALINA_OPTS are used to carry arguments, such as maximum heap memory settings or system properties, which are intended for the Java launcher. The difference between the two is that CATALINA_OPTS is cleared out when catalina is invoked with the stop command. In addition, as indicated by its name, the latter is targeted primarily at options for running a Tomcat instance.
- JPDA_OPTS sets the Java Platform Debugger Architecture (JPDA) options to support remote debugging of this Tomcat instance. The default options are set in the script. It chooses TCP/IP as the protocol used to connect to the debugger (transport=dt_socket), marks this JVM as a server application (server=y), sets the host and port number on which the server should listen for remote debugging requests (address=8000), and requires the application to run until the application encounters a breakpoint (suspend=n).
- DEBUG_OPTS sets the -sourcepath flag when the Java Debugger is used to launch the Tomcat instance.
- The other variables are set as seen in the previous section.
- At this point, control passes to the main() method in Bootstrap.java. This is where the steps that are unique to script-based startup end. The rest of this article follows along with the logic coded into Bootstrap.java and Catalina.java.