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
Why How to Successfully Move a File in Linux While It Is Being Written To
Why Is 08 Not a Valid Integer Literal in Java
When Do You Use Varargs in Java
Maven Dependencies Are Failing With a 501 Error
Replacing a Fragment with Another Fragment Inside Activity Group
Convert JSON Array to Normal Java List
How to Whitelist App in Doze Mode Android 6.0
Android: Difference Between Onintercepttouchevent and Dispatchtouchevent
Obtaining the Thread Id for Java Threads in Linux
Eclipse Release Heap Back to System
Ioexception: Too Many Open Files
"Java.Sql.Sqlexception: I/O Error: Connection Reset" in Linux Server
Java's 'Tnameserv' Takes 3+ Minutes to Be "Ready", Why
Execute Bash Command Within Java Program