2

I have a spring boot application which I run using an executable jar file. Currently to stop the service we are just killing the process. I saw that we can use the following methods to shutdown the application gracefully.

ApplicationContext ctx = SpringApplication.run(Application.class, args);

and then somewhere in the code I can call ctx.close() Or we can use the following static method.

SpringApplication.exit(ApplicationContext, ExitCodeGenerator)

It works for us currently, but we are actually calling this ctx.close() method inside a controller as follows.

@RequestMapping("/shutdownSpringBoot")
public void shutdownApplication() {
    MyApplication.ctx.close(); // I'm saving the context returned by spring boot in a static variable inside my main class
}

When we hit this controller method via http the application is gracefully shutdown. But we dont want to do it this way. Is it possible to write a shell / batch script to trigger the java class inside which I can call the ctx.close() method ? We are looking for a shutdown script like the one we get from a standalone tomcat container (shutdown.bat / shutdown.sh), so that we can give our application as a jar file to our customers and they can start or stop the application by executing those scripts. (Which they are used to).

Thanks, Sanjay

rojo
  • 24,000
  • 5
  • 55
  • 101
SanjaySSN
  • 229
  • 1
  • 3
  • 6
  • Sending a SIGINT *is* graceful and initiates what you described above. Your stop script could be a one-liner that reads application.pid and passes it to kill. – kryger Mar 04 '16 at 08:38

3 Answers3

0

I think you can simply detect that you are running your jar as a command line utility by inspecting command line parameters and instead of loading whole Spring context and booting up the web application, you just HTTP access the local shutdownSpringBoot URL using built-in Java HTTP client.

wilx
  • 17,697
  • 6
  • 59
  • 114
0

You can create a shell script and directly shutdown the springboot application. Just make sure you register shutdown hook to your spring boot application. In the shutdown hook, you can close the context. You can check my answer here

Community
  • 1
  • 1
nav3916872
  • 978
  • 13
  • 20
0

I use PID file writer to write file and store Jar and Pid in folder with same name as of application name and shell scripts also have same name with start and stop in the end.

Main Class

@SpringBootApplication
public class MyApplication {

    public static final void main(String[] args) {
        SpringApplicationBuilder app = new SpringApplicationBuilder(MyApplication.class);
        app.build().addListeners(new ApplicationPidFileWriter());
        app.run();
    }
}

YML FILE

spring.pid.fail-on-write-error: true
spring.pid.file: /server-path-with-folder-as-app-name-for-ID/appName/appName.pid

Here is the start script(start-appname.sh):

shellScriptFileName=$(basename -- "$0")
shellScriptFileNameWithoutExt="${shellScriptFileName%.*}"
appName=${shellScriptFileNameWithoutExt:6}

PROCESS=$1
PIDS=`ps aux |grep [j]ava.*$appName.*jar | awk {'print $2'}`
if [ -z "$PIDS" ]; then
  echo "No instances of $appName is running..." 1>&2
else
  for PID in $PIDS; do
    echo "Waiting for the process($PID) to finish on it's own for 3 mins..."
    sleep 3m
    echo "FATAL:Killing $appName with PID:$PID."
    kill -9 $PID
  done
fi

# Preparing the java home path for execution
JAVA_EXEC='/usr/bin/java'

# Java Executable - Jar Path Obtained from latest file in directory
JAVA_APP=$(ls -t /server-path-with-folder-as-app-name/$appName/$appName*.jar | head -n1)

# JVM Parameters and Spring boot initialization parameters
JVM_PARAM="-Xms512m -Xmx1024m -Dspring.profiles.active=sit -Dcom.webmethods.jms.clientIDSharing=true"

# To execute the application.
FINAL_EXEC="$JAVA_EXEC $JVM_PARAM -jar $JAVA_APP"

# Making executable command using tilde symbol and running completely detached from terminal
`nohup $FINAL_EXEC  </dev/null >/dev/null 2>&1 &`

echo "$appName has been started successfully."

Here is the stop script(stop-appname.sh):

shellScriptFileName=$(basename -- "$0")
shellScriptFileNameWithoutExt="${shellScriptFileName%.*}"
appName=${shellScriptFileNameWithoutExt:5}

# Script to stop the application
PID_PATH="server-path-with-folder-as-app-name-for-PID/$appName/$appName.pid"

if [ ! -f "$PID_PATH" ]; then
   echo "Process Id FilePath($PID_PATH) Not found"
else
pid=`cat $PID_PATH`
    if [ ! -e /proc/$pid -a /proc/$pid/exe ]; then
        echo "$appName was not running.";
    else
       kill $pid;
       echo "Gracefully stopping $appName with PID:$pid..."
    fi
fi
Anand Varkey Philips
  • 1,811
  • 26
  • 41