I have a script that needs to run after tomcat has finished starting up and is ready to start deploying applications. I'm using $TOMCAT_HOME/bin/startup.sh
which returns immediately. How can I wait until tomcat has finished starting up?
8 Answers
There are probably several ways to do this. The trick we use is:
#!/bin/bash
until [ "`curl --silent --show-error --connect-timeout 1 -I http://localhost:8080 | grep 'Coyote'`" != "" ];
do
echo --- sleeping for 10 seconds
sleep 10
done
echo Tomcat is ready!
Hope this helps!

- 32,152
- 8
- 53
- 57
-
1if you use e.g. grep '302 Found' instead of grep 'Coyote' then this can be used on non-Tomcat servers as well - e.g. to check the readyness up of a Jenkins server. – vorburger May 04 '15 at 19:21
-
Even better: use `curl --silent --write-out '%{response_code} -o /dev/null '[url]'`. That gives you the response code, and you can use it with `[` to test any value you think is appropriate. You'll probably also want to limit redirects, too. – Christopher Schultz Sep 08 '16 at 21:38
-
Instead of `--connect-time` I used `--max-time`, as Tomcat can connect and yet not be ready to deliver a page. – Rob Stoecklein Nov 05 '18 at 21:08
-
Why we need sleep ? – Ori Marko Mar 14 '19 at 08:26
-
@user7294900 without sleep, it would probably eat up all your cpu as it would loop as many times as possible while it runs. – tugi Oct 15 '19 at 03:11
It's not hard to implement programaticaly. You can implement org.apache.catalina.LifecycleListener and then you'll have
public void lifecycleEvent(LifecycleEvent lifecycleEvent) {
if(lifecycleEvent.getType().equals(Lifecycle.START_EVENT))
//do what you want
}
}
in web.xml :
<Context path="/examples" ...>
...
<Listener className="com.mycompany.mypackage.MyListener" ... >
...
</Context>
Please notice that some things could differ between 6-9 Tomcats.

- 779
- 7
- 8
-
Seems interesting. Mind to explain what should I do next with this class? How to register it to tomcat, how this code can communicate with my script/ant, etc? – Thariq Nugrohotomo Dec 23 '15 at 07:40
Are you still looking for an answer? It depends on your definition of started. If your definition of started is "Now its safe to stop" then you might want to verify if port 8005 is listening.

- 1,152
- 1
- 12
- 28
Depends on what you mean by finishing. What do you want to wait for?
You could, for example, have a script that hits a URL repeatedly until it gets a desirable result that would only be available once the app is properly initialized.
You could also have a context listener that writes out an "I'm ready" file that you use to signal the readiness of your application. (If you do this, be sure the file doesn't exist before starting your app container).

- 89,080
- 21
- 111
- 133
I needed this to test from jenkins if the tomcat from the remote server started for a system check.
until [[ `ssh -o StrictHostKeyChecking=no root@${DEPLOY_HOST} 'netstat -tulpn | grep 8005'` != "" ]] ; do echo "waiting for tomcat"; sleep 6; done

- 596
- 4
- 23
There isn't an easy method. As far as startup.sh and catalina.sh are concerned, tomcat is running when they finish. Although, internally, tomcat is still initializing and starting contexts.
It would help to know if you were trying to find out if your context finished loading or if you are just wanting a general, "Tomcat is runnnig although your contexts might not be completely loaded..."
If it is the latter you could create a web app that simply has a context listener that will execute a script using Runtime. If you were handy, you could make the webapp configuable via the web.xml file to accept a parameter that points to the script to execute.

- 8,853
- 3
- 35
- 44
Personally, I would just watch catalinas log for a specific string depending on how your setup and what exact phase your looking for.

- 29,950
- 9
- 48
- 62
I have done it with the following code in jenkins pipelinescript with tomcat. Before i just call
sudo /bin/systemctl restart tomcat
And have an entry in my sudoers file for the jenkins user.
Now here is the oneliner:
until [ "$(curl -w '%{response_code}' --no-keepalive -o /dev/null --connect-timeout 1 -u USERNAME:PASSWORD http://localhost:8080/manager/text/list)" == "200" ]; do echo --- sleeping for 1 second; sleep 1; done
Better readable:
until [ "$(curl -w '%{response_code}' --no-keepalive -o /dev/null --connect-timeout 1 -u USERNAME:PASSWORD http://localhost:8080/manager/text/list)" == "200" ];
do echo --- sleeping for 1 second;
sleep 1;
done

- 99
- 11