About Rama Krishnan

Ramki is a Application Developer working in the C-DAC, Pune. He has Extensive Design and Development experience in Java, Java Server Faces, Servlets, Java Persistent API (Hibernate), CDI, EJB and experience in applying Design Patterns of JavaEE Architecture.

Multiple Tomcat Instances on Single Machine

In this post we will see how to run multiple tomcat instances on a single machine and under a single user account.

We first see the tomcat directory structure, where each folder has the following purpose:

bin –  contains all binary and script files for running tomcat.
lib – contains all shared libraries used for tomcat
conf – contains configuration information like which port tomcat can bind, etc.
logs – contains all log files
temp – this folder is used by Tomcat for temporary files
webapps – this folder is very important, we put here all the application war files
work – if an application contains JSPs, then each JSP is translated and converted into a servlet and is stored here
When we run Tomcat, it uses 5 environment variables. They are:
  • CATALINA_HOME
  • CATALINA_BASE
  • CATALINA_TMPDIR
  • JRE_HOME/JAVA_HOME
  • CLASSPATH
In the above list, CATALINA_HOME and JAVA_HOME are mandatory environment variables. All others are optional and can be calculated using CATALINA_HOME.
CATALINA_HOME – this environment variable should point to tomcat base folder, where tomcat binary are  installed/extracted. so based on CATALINA_HOME we can get bin and lib folder
CATALINA_BASE – If we not specified then CATALINA_HOME value is set. This variable pointed to configuration and webapps folder. Based on this variable server uses conf, logs, temp, webapps, work folders.

A usual way to run Tomcat is to only set the CATALINA_HOME environment variable and run the startup.sh script file. The startup.sh file automatically calculates and assigns the values of other variables which we have not set.

The startup.sh file sets the environment variable and  then calls catalina.sh. This file reads CATALINA_BASE value, attaches conf i.e $CATALINA_BASE/conf folder and gets server.xml. This file is the heart of Tomcat’s configuration. It contains all configuration information, like shutdown port, connector post, host name, application folder, etc. For example, Tomcat usually uses 8080 as a connector port, so we can access it at http://localhost:8080/.

If we set the $CATALINA_BASE explicitly, then Tomcat uses our variable to search and get the server.xml file from our target place, i.e what we specified in CATALINA_BASE. 
This trick can be used to run multiple Tomcat instances in a single machine. We don’t need to change the CATALINA_HOME value. We just need to change the CATALINA_BASE value before start/shutdown Tomcat.

Create one folder named “tomcat-instance1” and copy conf, logs, temp, webapps, work folder from CATALINA_HOME folder and change conf/server.xml file in tomcat-instance1. We need to change these ports: shutdown port, connector port, ajp port and redirect port.

Shutdown port – This port is used for shutting down Tomcat. When we call the shutdown.sh script, it sends a signal to shutdown port. This port is where the Tomcat Java process listens. If such signal is received, the process then cleans up and exits by itself.
Connector port -This port is the actual port that exposes the application to an outside client. 
ajp port – This port may be used by a web server (e.g. Apache httpd server) to communicate with Tomcat. This port is also used when we setup a load balanced server.
Redirect port – If the Connector is supporting non-SSL requests and a request is received for which a security constraint requires SSL, Catalina will automatically redirect the request to this port. 

Let’s see the sample server.xml file:

<server port="8005" shutdown="SHUTDOWN">
	.....
	<connector
		connectiontimeout="20000"port="8080"
		protocol="org.apache.coyote.http11.Http11NioProtocol"
		redirectport="8443" />
	<connector port="8009" protocol="AJP/1.3" redirectport="8443" />
</server>

So, we change these ports to different numbers, because once a port is binded, then an other process can’t bind it again. In tomcat-instance1/conf/server.xml file I configured server port =8105, connector port = 8181, ajp port = 8109.

<server port="8105" shutdown="SHUTDOWN">
	.....
	<connector
		connectiontimeout="20000" port="8181"
		protocol="org.apache.coyote.http11.Http11NioProtocol"
		redirectport="81443" />
	<connector port="8109" protocol="AJP/1.3" redirectport="81443" />
</server>

Now we can create two script files for starting up and shutting down the tomcat-instance1.

startup-instance1.sh

export CATALINA_BASE= /home/ramki/tomcat-instance1
cd $CATALINA_HOME/bin
./startup.sh

shutdown-instance1.sh

export CATALINA_BASE= /home/ramki/tomcat-instance1
cd $CATALINA_HOME/bin
./shutdown.sh

Here we explicitly set the CATALINA_BASE variable and point it to the new tomcat-instance1. Then we go to the CATALINA_HOME/bin folder because all binary files for running tomcat are still present there. Then we use the startup/shutdown cripts.

Based on the above technique, we can create many instance folders and change the conf/server.xml file port values and run that instance with their own newly created script files.

Reference: Running Multiple Tomcat Instances on Single Machine from our JCG partner Rama at the Ramkitech blog (original text was modified for readability reasons).

Related Articles :

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

11 Responses to "Multiple Tomcat Instances on Single Machine"

  1. Nikola Tošić says:

    One comment: also, if using java debugging port, you should change debugger port in different scripts.
    This did not work for me, until i set $JAVA_OPTS variable to use:
    -Xdebug -Xrunjdwp:transport=dt_socket,address=1045
    in other instance instead of
    -Xdebug -Xrunjdwp:transport=dt_socket,address=1044

    as debugging options.

  2. Jerald Sebastian says:

    This is very useful. However there is no mention about where the two new script files (shutdown-instance1.sh and shutdown-instance1.sh) can go. Obviously there will not be any issue for the tomcat to start up. But if the applications are looking for files relative to working directory there could be problems. Application that works in the very first instance of tomcat, would fail in the second tomcat instance. So it is recommended to have the new script files in a folder named ‘bin’.

  3. Jerald Sebastian says:

    One more thing. Please remember to remove all tomcat related applications (manager, docs, examples, default context etc) as required for your business. Some one in the team that sets up Tomcat instances for us, seems to blindly refer the steps in this blog and left out the default context :) With that the main domain points to the default tomcat page which has links to tomcat and oracle :)

  4. good trick to make multiple instance without multiple copies of tomcat

  5. João Martins says:

    Hi,
    i tried this and almoust everything works, although when i shutdown the server, it hangs in this line:

    INFO: Destroying ProtocolHandler [“http-bio-8183″] and if i start it this is what i get:

    INFO: Initializing ProtocolHandler [“http-bio-8183″]
    Mar 31, 2014 4:17:01 PM org.apache.coyote.AbstractProtocol init
    SEVERE: Failed to initialize end point associated with ProtocolHandler [“http-bio-8183″]
    java.net.BindException: Address already in use :8183
    at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:391)
    at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:554)
    at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:409)
    at org.apache.coyote.http11.AbstractHttp11JsseProtocol.init(AbstractHttp11JsseProtocol.java:119)
    at org.apache.catalina.connector.Connector.initInternal(Connector.java:956)
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
    at org.apache.catalina.core.StandardService.initInternal(StandardService.java:559)
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
    at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:815)
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
    at org.apache.catalina.startup.Catalina.load(Catalina.java:594)
    at org.apache.catalina.startup.Catalina.load(Catalina.java:619)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:281)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:449)
    Caused by: java.net.BindException: Address already in use
    at java.net.PlainSocketImpl.socketBind(Native Method)
    at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:376)
    at java.net.ServerSocket.bind(ServerSocket.java:376)
    at java.net.ServerSocket.(ServerSocket.java:237)
    at java.net.ServerSocket.(ServerSocket.java:181)
    at org.apache.tomcat.util.net.DefaultServerSocketFactory.createSocket(DefaultServerSocketFactory.java:49)
    at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:378)
    … 17 more

    Mar 31, 2014 4:17:01 PM org.apache.catalina.core.StandardService initInternal
    SEVERE: Failed to initialize connector [Connector[HTTP/1.1-8183]]
    org.apache.catalina.LifecycleException: Failed to initialize component [Connector[HTTP/1.1-8183]]
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:106)
    at org.apache.catalina.core.StandardService.initInternal(StandardService.java:559)
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
    at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:815)
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
    at org.apache.catalina.startup.Catalina.load(Catalina.java:594)
    at org.apache.catalina.startup.Catalina.load(Catalina.java:619)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:281)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:449)
    Caused by: org.apache.catalina.LifecycleException: Protocol handler initialization failed
    at org.apache.catalina.connector.Connector.initInternal(Connector.java:958)
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
    … 12 more
    Caused by: java.net.BindException: Address already in use :8183
    at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:391)
    at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:554)
    at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:409)
    at org.apache.coyote.http11.AbstractHttp11JsseProtocol.init(AbstractHttp11JsseProtocol.java:119)
    at org.apache.catalina.connector.Connector.initInternal(Connector.java:956)
    … 13 more
    Caused by: java.net.BindException: Address already in use
    at java.net.PlainSocketImpl.socketBind(Native Method)
    at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:376)
    at java.net.ServerSocket.bind(ServerSocket.java:376)
    at java.net.ServerSocket.(ServerSocket.java:237)
    at java.net.ServerSocket.(ServerSocket.java:181)
    at org.apache.tomcat.util.net.DefaultServerSocketFactory.createSocket(DefaultServerSocketFactory.java:49)
    at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:378)
    … 17 more

    Mar 31, 2014 4:17:01 PM org.apache.catalina.startup.Catalina load
    INFO: Initialization processed in 791 ms
    Mar 31, 2014 4:17:01 PM org.apache.catalina.core.StandardService startInternal
    INFO: Starting service Catalina
    Mar 31, 2014 4:17:01 PM org.apache.catalina.core.StandardEngine startInternal
    INFO: Starting Servlet Engine: Apache Tomcat/7.0.26
    Mar 31, 2014 4:17:01 PM org.apache.catalina.startup.HostConfig deployWAR
    INFO: Deploying web application archive /home/remember/remembermeJM/webapps/RememberMeServer.war
    Mar 31, 2014 4:17:05 PM org.apache.catalina.startup.HostConfig deployWAR
    INFO: Deploying web application archive /home/remember/remembermeJM/webapps/axis2.war
    [INFO] Clustering has been disabled
    [INFO] Deploying module: metadataExchange-1.6.2 – file:/home/remember/remembermeJM/webapps/axis2/WEB-INF/modules/mex-1.6.2.mar
    [INFO] Deploying module: addressing-1.6.2 – file:/home/remember/remembermeJM/webapps/axis2/WEB-INF/modules/addressing-1.6.2.mar
    [INFO] Deploying module: jaxws-1.6.2 – file:/home/remember/remembermeJM/webapps/axis2/WEB-INF/modules/axis2-jaxws-mar-1.6.2.mar
    [INFO] Deploying module: mtompolicy-1.6.2 – file:/home/remember/remembermeJM/webapps/axis2/WEB-INF/modules/mtompolicy-1.6.2.mar
    [INFO] Deploying module: soapmonitor-1.6.2 – file:/home/remember/remembermeJM/webapps/axis2/WEB-INF/modules/soapmonitor-1.6.2.mar
    [INFO] Deploying module: ping-1.6.2 – file:/home/remember/remembermeJM/webapps/axis2/WEB-INF/modules/ping-1.6.2.mar
    [INFO] Deploying module: script-1.6.2 – file:/home/remember/remembermeJM/webapps/axis2/WEB-INF/modules/scripting-1.6.2.mar
    [INFO] Deploying Web service: PictureWS.aar – file:/home/remember/remembermeJM/webapps/axis2/WEB-INF/services/PictureWS.aar
    [INFO] Deploying Web service: LocationWS.aar – file:/home/remember/remembermeJM/webapps/axis2/WEB-INF/services/LocationWS.aar
    [INFO] Deploying Web service: RegistrationIdWS.aar – file:/home/remember/remembermeJM/webapps/axis2/WEB-INF/services/RegistrationIdWS.aar
    [INFO] Deploying Web service: version-1.6.2.aar – file:/home/remember/remembermeJM/webapps/axis2/WEB-INF/services/version-1.6.2.aar
    [INFO] Deploying Web service: AccelerometerWS.aar – file:/home/remember/remembermeJM/webapps/axis2/WEB-INF/services/AccelerometerWS.aar
    [INFO] Deploying Web service: AmplitudeWS.aar – file:/home/remember/remembermeJM/webapps/axis2/WEB-INF/services/AmplitudeWS.aar
    Mar 31, 2014 4:17:09 PM org.apache.catalina.startup.Catalina start
    INFO: Server startup in 7887 ms

    I have another instance running. But i have to have it running, because they are different applications. Can someone help me

    • Ramki says:

      the problem is ur using port 8183, but its already used by some process. check the netstat -tlpn command.

      change the port to different one. and make sure all are unique ports (unused).

      • João Martins says:

        But this also happens in one instance i have with port 8181 and before this instance was working properly is this some kind of problem where there is a proccess running in this ports that weren’t shutdown and still running?

Leave a Reply


five − = 3



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close