Wait Until Tomcat Finishes Starting Up

Wait until tomcat finishes starting up

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!

Wait till tomcat startup is over

To automate the process, you should copy the app to be deployed into tomcat deployments folder before you start the server up. If you copy any .war package to TOMCAT/webapps folder, it will get deployed by Tomcat when it starts up.

So what you need to do is to just copy the file. here are four different examples on how to do that in Java. Either that, or you can just exec a copy command.

Possibly easiest and least error prone is to do it using Files, in java 7:

Files.copy(source.toPath(), dest.toPath());

and after that is finished, then exec start command.


Update: with shutdown, you have the wait issue. You can wait doing something like this in a batch file:

CALL shutdown.bat
:LOOP
tasklist /FI "WINDOWTITLE eq Tomcat" | find /C /I ".exe" > NUL
IF ERRORLEVEL 1 (
GOTO :EOF
) ELSE (
ECHO Tomcat is still running
SLEEP 1
GOTO LOOP
)

This code assumes a Tomcat window with name 'Tomcat'. If you run Tomcat as a service, for example, that assumption is not true. For service however there are more reliable means using sc query:

SC stop "tomcat"
:LOOP
SC query "tomcat" | FIND "STATE" | FIND "RUNNING" > NUL
IF ERRORLEVEL 1 (
GOTO :EOF
) ELSE (
ECHO Tomcat is still running
SLEEP 1
GOTO LOOP
)

Here assuming service name "tomcat".

Update2: forgot we're talking about java here - with the bat above, you can use java .waitFor(), or you can program the same logic in a java file as well.

Monitor tomcat in Bash until it finishes deploying war or application

With systemd

If you start Tomcat with systemctl or catalina.sh uses systemctl something like this could be done.
Change demo.war to your war name, Adjust the sleep period to show as many . (dots) as needed. If it takes 30 secs to deploy, it will show 30 dots.

while ! systemctl status tomcat --no-pager | grep -q 'Deployment of.*demo.war.* has finished'; do \
echo -ne "."; sleep 1; \
done && echo "War deployed"

With catalina.sh

If catalina.sh run from Apache package is used (using catalina.sh start will not work)

while read -r line; do
if echo "$line" | grep -q 'Deployment of.*[/]demo.war.* has finished' ; then
echo "***** $line"
# do some stuff with your app
break
else
echo "---- $line"
fi
done < <(./bin/catalina.sh run 2>&1 &) && echo "War deployed"
# start tomcat ----------^
# with console output but in background

./bin/catalina.sh stop

Monitoring log file

Might required permissions to the log file.

log='/var/log/tomcat/catalina.2021-07-05.log'
msg='Deployment of.*[/]demo.war.* has finished'
while read -r line; do
if echo "$line" | grep -q "$msg" ; then
echo "***** $line"
# do some stuff with your app
break
else
echo "---- $line"
fi
done < <(tail -n 1 -f "$log")
echo "War deployed"
sleep 5 # get a chance to see the previous message :-p

If starting tomcat from Eclipse

log='/home/lmc/workspace/.metadata/.plugins/org.eclipse.wst.server.core/logs/catalina.out'
msg='Deployment of deployment descriptor .*demo.xml. has finished'
# same code as above

With Tomcat Manager

With Tomcat manager configured:

until ! curl -u userblah:s3cr3t --silent "http://localhost:8080/manager/text/list" | grep '^[/]demo:running'; do
echo "Deploying 'demo' app"
sleep 1
done

With SpringBoot Actuator

If your Spring boot app uses Spring Boot Actuator and is configured as

management.endpoints.web.exposure.include=health
management.endpoints.web.base-path=/actuator
management.server.port=8081
management.server.address=127.0.0.1

It can be monitored as:

until curl --silent "http://127.0.0.1:8081/actuator/health" | grep -q 'status":"UP'; do
echo "Deploying 'demo' app"
sleep 1
done
echo "is UP"

How to prevent service from starting until after Catalina has started

You won't see Server startup, because you highjacked the initializing thread and started to do polling with it. The server would be started after your servlet is initialized, but it never finishes initializing since you call startPoll() in init() and it never returns.

Instead of hand-crafted polling with an infinite loop and manual 2 minute sleep, look into scheduling, for example with Quartz or at least a ScheduledExecutorService, here's a Tomcat based example.

Tomcat to indicate in the logs when all webapps finished loading

So, the easy answer is that you can't.

I've found the Tomcat Lifecycleevents, but they are only for Tomcat events, and only for start and stop, not for finished starting.

Once Tomcat starts there's no way for it to know that a specific app has finished. Or even a group of apps.

Wait until tomcat finishes starting up

So there's no way to print to the logs. Bummer.

I'll make every web app provide a heartbeat and consider it "live" when all the heartbeats come back.

Ant Script after Tomcat Startup

An easy way without dealing with anything related to Tomcat:

<!-- run tomcat here -->

<!-- wait for the server to be available -->
<waitfor>
<http url="http://host:port">
</waitfor>

<!-- run other ant scripts from here... -->


Related Topics



Leave a reply



Submit