Tomcat

Tomcat is an open source Java
Servlet container
developed by the Apache Software Foundation.
Note
Tomcat currently exists under four stable branches:
7
,
8
,
9
and
10
, . None of these version deprecates the preceding. Instead,
each branch is the implementation of a couple of the "Servlet" and "JSP" Java standards
. The last versions are officially supported in Arch Linux:
tomcat8
AUR
,
tomcat9
and
tomcat10
. Check the version you need depending on your web applications requirements.
Installation
Install one of
tomcat8
AUR
,
tomcat9
, or
tomcat10
.
If deploying Tomcat onto a production environment, consider installing
tomcat-native
. The native library for Tomcat configures the server to use the Apache Portable Runtime (APR) library's network connection (socket) and RNG implementations. It uses native 32- or 64-bit code to enhance performance and is sometimes used in production environments where speed is crucial. No configuration is necessary for default Tomcat installations. More information is available in the
official Tomcat docs
.
Using tomcat-native will remove the following warning in
catalina.err
:
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path [...]
Filesystem hierarchy
Replace the
n
with your installed version (8, 9, 10).
Pathname
Use
/etc/tomcat
n
Configuration files. Among some:
tomcat-users.xml
(defines users allowed to use administration tools and their roles),
server.xml
(Main Tomcat configuration file),
catalina.policy
(security policies configuration file)
/usr/share/tomcat
n
Main Tomcat folder containing scripts and links to other directories
/usr/share/java/tomcat
n
Tomcat Java libraries (jars)
/var/log/tomcat
n
Log files
not
handled by
systemd
(see
#Logging
)
/var/lib/tomcat
n
/webapps
Where Tomcat deploys your web applications
/var/tmp/tomcat
n
Where Tomcat store your webapps' data
Initial configuration
In order to be able to use the manager webapp and the admin webapp, you need to edit
/etc/tomcat
n
/tomcat-users.xml
.
Uncomment the "role and user" XML declaration and modify it to enable roles
tomcat
,
admin-gui
,
admin-script
and/or
manager-gui
,
manager-script
,
manager-jmx
,
manager-status
, depending on your needs (see
Configuring Manager Application Access
).
To keep it short,
tomcat
is the mandatory role used to run,
manager-*
are roles able to administer web applications and
admin-*
are full right administrator roles on the Tomcat server.
Here is a bare configuration file that declares some of these roles along with usernames and passwords (be sure to change the following [CHANGE_ME] passwords to something secure):
/etc/tomcat
n
/tomcat-users.xml
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
  <role rolename="tomcat"/>
  <role rolename="manager-gui"/>
  <role rolename="manager-script"/>
  <role rolename="manager-jmx"/>
  <role rolename="manager-status"/>
  <role rolename="admin-gui"/>
  <role rolename="admin-script"/>
  <user username="tomcat" password="
[CHANGE_ME]
" roles="tomcat"/>
  <user username="manager" password="
[CHANGE_ME]
" roles="manager-gui,manager-script,manager-jmx,manager-status"/>
  <user username="admin" password="
[CHANGE_ME]
" roles="admin-gui"/>
</tomcat-users>
Keep in mind that Tomcat must be restarted each time a modification is made to this file.
This
blog post
gives a good description of these roles.
To have read permissions on the configuration files and work well with some IDEs, you must add your user to the
tomcat
n
user group
.
Start/stop Tomcat
Start
the
tomcat
n
.service
.
Once Tomcat is started, you can visit this page to see the result:
http://localhost:8080
. If a nice Tomcat local home page is displayed, this means your Servlet container is up and running and ready to host you web apps. If the startup script failed or you can only see a Java error displayed in you browser, have a look at startup logs using systemd's
journalctl
. Google is full of answers on recurrent issues found in Tomcat logs.
This article or section is out of date.
Reason:
/etc/conf.d/tomcat
n
does not exist at least on tomcat{9,10}. Check where the new
CATALINA_OPTS
exists. (Discuss in
Talk:Tomcat
)
Note
To improve security, Arch Linux's Tomcat packages use the
jsvc
binary from Apache's
common-daemons
. Tomcat's
systemd
service runs this Apache binary with root privileges which itself starts Tomcat with an underprivileged user (
tomcat
n
:tomcat
n
in Arch Linux). This prevents malicious code that could be executed in a bad web application from causing too much damage. This also enables the use of ports under 1024 if needed. See
man jsvc
for options available and pass them through the
CATALINA_OPTS
environment variable declared in
/etc/conf.d/tomcat
n
.
Alternate "manual" way
Tomcat can also be controlled directly using upstream scripts:
/usr/share/tomcat/bin/{startup.sh,shutdown.sh,..}
This can be useful to debug applications or even debug Tomcat, but do not use it to start Tomcat for the first time as doing so can set some permissions wrongly and stop web apps from working. In order to be able to use these scripts, some further configuration may be needed. Be aware that using these scripts prevents the jsvc security advantage described above.
Deploy and handle web applications
Tomcat is bundled with 5 already deployed web applications (change localhost with your server's FQDN if needed):
The default home page:
http://localhost:8080/
Tomcat's local documentation:
http://localhost:8080/docs/
Examples of Servlets and JSP:
http://localhost:8080/examples/
The host-manager to handle virtual hosts:
http://localhost:8080/host-manager/
The manager to administer web applications:
http://localhost:8080/manager/html/
The GUI way
Probably the easiest way is to use the manager webapp
http://localhost:8080/manager/html
. Use the username/password you defined as
manager
in
tomcat-users.xml
. Once logged in, you can see five already deployed web applications. Add yours through the "Deploy" area and then stop/start/undeploy it with the "Applications" area.
The CLI way
One can also just copy the WAR file of the application to directory
/usr/share/tomcat
n
/webapps
. For that later, be sure that the
autoDeploy
option is still set for the right host as shown here:
/etc/tomcat
n
/server.xml
...
<Host name="localhost"  appBase="webapps"
      unpackWARs="true"
autoDeploy="true"
>
...
Otherwise simply restart the tomcat service.
Hosting files outside the webapps folder
If you want to keep your project outside the webapps folder, this is possible by creating a
Context
. 
Go to
/etc/tomcat
n
/Catalina/localhost/
and create your context. A context is a simple xml file which specifies where tomcat should look for the project. The basic format of the file is:
/etc/tomcat
n
/Catalina/localhost/whatShouldFollowLocalhost.xml
<Context path="/whatSholdFollwLocalhost" docBase="/where/your/project/is/" reloadable="true"/>
A working example is as follows. This assumes that the project is hosted somewhere in the users /home-folder.
/etc/tomcat
n
/Catalina/localhost/myProject.xml
<Context path="/myProject" docBase="/home/archie/code/jsp/myProject" reloadable="true"/>
The files can now be hosted in
/home/archie/code/jsp/myProject/
. To see the project in your webbrowser, go to
http://localhost:8080/myProject
.
If tomcat is unable to load the files, it might be an issue with permissions. Making
/home/archie/code/jsp/myProject
executable
should fix the issue.
Logging
Tomcat when used with official Arch Linux packages uses systemd's
journalctl
for startup log
. This means that files
/var/log/tomcat
n
/catalina.err
and
/var/log/tomcat
n
/catalina.out
are
not
used. Other logs such as access logs and business logs defined in
/etc/tomcat
n
/server.xml
as
Valve
will still by default end up in
/var/log/tomcat
n
/
.
To restore upstream style logging, use a
drop-in file
to change both
SYSLOG
for the absolute paths of log files.
Further setup
Basic configuration can be made through the virtual host manager web application:
http://localhost:8080/host-manager/html
. Provide the username/password you set in
tomcat-users.xml
. Other options are tweaked in configuration files in
/etc/tomcat
n
, the most important being
server.xml
. Using these files is out of the scope of this 101 wiki page. Please have a look at the
latest official Tomcat documentation
for more details.
Migrating from previous versions of Tomcat
As said in the introduction,
Tomcat 10 does not deprecate Tomcat 9, Tomcat 9 does not deprecate Tomcat 8 and so on
. They all are implementations of Servlet/JSP standards. Hence you must first determine
which version
of Tomcat you need depending on the versions of Servlet/JSP your application uses. If you need to migrate, the official website gives
instructions on how to handle such a process
.
Using Tomcat with a different JRE/JDK
Apart from installing the desired JRE/JDK, the only requirement is to set the
TOMCAT_JAVA_HOME
variable with a
drop-in file
:
/etc/systemd/system/tomcat
n
.service.d/start.conf
[Service]
Environment=TOMCAT_JAVA_HOME=/usr/lib/jvm/java-8-openjdk
Security configuration
This article or section is out of date.
Reason:
Both referenced guides are talking about tomcat versions that have
long
been EOL. (Discuss in
Talk:Tomcat
)
This page gives the bare minimum to get your first web application to run on Tomcat. It is not intended to be the definitive guide to administering Tomcat (it is a job of its own). The official Tomcat website will provide all necessary official matter. One could also refer to this
O'Reilly page
and this
unidata one
. 
Still, here are some security tips to get you started:
Keep your Tomcat installation up to date to get the latest fixes to security issues
Remove unwanted default applications such as
examples
,
docs
, default home page
ROOT
("_" in the
manager
webapp). This prevents potential security holes to be exploited. Use the
manager
for that.
For more security, you could even remove the host-manager and manager web applications. Keep in mind that the later is useful to deploy web applications.
Disable the WAR auto-deploy option. This would prevent someone who gained restricted access to the server to copy a WAR into the
/usr/share/java/webapps
directory to get it running. Edit
server.xml
and set the
autoDeploy
to
false
:
/etc/tomcat
n
/server.xml
...
<Host name="localhost"  appBase="webapps"
      unpackWARs="true"
autoDeploy="false"
>
...
Anonymize Tomcat's default error page to prevent potential attackers to retrieve Tomcat's version. To see what Tomcat says by default, just visit an nonexistent page such as
http://localhost:8080/I_dont_exist
. You get a 404 error page with Tomcat's version at the bottom.
To anonymize this, edit/open the following JAR (Editors like
vim
can edit zips directly)
/usr/share/tomcat
n
/lib/catalina.jar
And edit the following file:
org/apache/catalina/util/ServerInfo.properties
...
server.info=
server.number=
server.built=
...
Disable unused
connectors
in
server.xml
Keep restricted access to
/etc/tomcat
n
/server.xml
. Only
tomcat
user and/or
root
should be able to read and write this.
Keep
jsvc
usage. Do not use upstream startup scripts unless particular reason as explained in the security note above.
Use strong different passwords for each user in
tomcat-users.xml
, give roles to users who really need them and even disable usernames/roles you do not use/need.
One can even crypt
tomcat-users.xml
passwords using the following upstream script:
/usr/share/tomcat
n
/bin/digest.sh -a sha-512 -h org.apache.catalina.realm.MessageDigestCredentialHandler NEW_PASSWORD
This will output something like:
NEW_PASSWORD:58adca01951a24aebce28f4d7a759aa30ef2f38bc54e41e51071c257ed4a1a9b$1$b4ccaafa86c26dea13825d35da73f9d11ce63f5deae15a13aafb835bdaf710d38922843c8065f35f245a20b1d2df9b20ddf2c005990512c598a62514f78cf3d2
Paste the hashed part in place of the clear password in
tomcat-users.xml
and add the following to
server.xml
:
/etc/tomcat
n
/server.xml
<Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase">
               <CredentialHandler className="org.apache.catalina.realm.MessageDigestCredentialHandler"
                                  algorithm="sha-512"/>
        </Realm>
      </Realm>
  ...
/>
Note that this may not be relevant because only root and/or tomcat is supposed to have read/write access to that file. If an intruder manages to gain root access, they would not need such passwords to mess with your applications/data anyway. Be sure to keep restricted read and write access to that file, and always know what you are deploying!
Troubleshooting
Tomcat service is started, but page is not loaded
First, check
/etc/tomcat
n
/tomcat-users.xml
for any syntax error. If everything is fine and
tomcat
n
is correctly running, run
journalctl -r
as root to check the logs for any exception thrown (see
#Logging
). If you read anything like
java.lang.Exception: Socket bind failed: [98] Address already in use
, this is due to some other service listening on the same port. For instance, it is possible that
Apache HTTP Server
and Tomcat are listening on the same port (if for example you have Apache running on port 8080 with
Nginx
serving it as a proxy on port 80). If this is the case, edit the
/etc/tomcat
n
/server.xml
file and change the Connector port to something else under
<Service name="Catalina">
:
/etc/tomcat
n
/server.xml
<?xml version='1.0' encoding='utf-8'?>
...
...
<!-- Change port from 8080 to something else, like 8090 -->
<Service name="Catalina">
    <Connector executor="tomcatThreadPool"
                 port="8090" protocol="HTTP/1.1"
                 connectionTimeout="20000"
                 redirectPort="8443" />
...
...
</Service>
Finally,
restart
tomcat
n
and
httpd
services.
If you have no solution and you are in a VM, it can help to delete
/dev/random
and create it again (cf.
Solution: FUTEX_WAIT hangs Java on Linux / Ubuntu in vmware or virtual box
):
# rm /dev/random 
# mknod -m 644 /dev/random c 1 9
Or another solution to keep it even after a reboot is to modify
/usr/lib/jvm/java-8-openjdk/jre/lib/security/java.security
(for example) to point to
/dev/urandom
/