DevOps Zone is brought to you in partnership with:

I'm a software developer for whom coding is a way of life as well as a hobby. Focused on slimming enterprise class systems, strongly interested in new technologies and continuously improving the software delivery process. My great passion are lightweight applications, in which the ratio of provided functionality to the code is as smallest as possible. Co-founder of the agile software house Codearte. Confitura conference organizer. Jakub is a DZone MVB and is not an employee of DZone and has posted 14 posts at DZone. You can read more from them at their website. View Full User Profile

Managing Spring Boot Application

05.08.2014
| 7950 views |
  • submit to reddit
Spring Boot is a brand new application framework from Spring. It allows fabulously quick development and rapid prototyping (even including CLI). One of its main features is to work from single "uber jar" file. By "uber jar" I mean that all dependencies, even an application server like Tomcat or Jetty are packed into a single file. In that we can start web application by typing 
java -jar application.jar
The only thing we're missing is the managing script. And now I want to dive into that topic.

Of course to do anything more than starting our application we need to know its PID. Spring Boot has a solution named ApplicationPidListener. To use it we need to tell SpringApplication we want to include this listener. And there are to ways to achieve that.


Easiest way it to create file META-INF/spring.factories containing lines:
org.springframework.context.ApplicationListener=\
org.springframework.boot.actuate.system.ApplicationPidListener

Second way allows us to customize listener by specifying own name or location for PID file.
public class Application {
public static void main(String[] args) {
SpringApplication springApplication =
new SpringApplication(Application.class);
springApplication.addListeners(
new ApplicationPidListener("app.pid"));
springApplication.run(args);
}
}

Now, when we already have our PID file we need bash script providing standard operations like stop, start, restart and status checking. Below you can find simple script solving that challenge. Of course remember to customize highlighted lines :)
#!/bin/sh
JARFile="application.jar"
PIDFile="application.pid"
SPRING_OPTS="-DLOG_FILE=application.log"
function check_if_pid_file_exists {
if [ ! -f $PIDFile ]
then
echo "PID file not found: $PIDFile"
exit 1
fi
}
function check_if_process_is_running {
if ps -p $(print_process) > /dev/null
then
return 0
else
return 1
fi
}
function print_process {
echo $(<"$PIDFile")
}
case "$1" in
status)
check_if_pid_file_exists
if check_if_process_is_running
then
echo $(print_process)" is running"
else
echo "Process not running: $(print_process)"
fi
;;
stop)
check_if_pid_file_exists
if ! check_if_process_is_running
then
echo "Process $(print_process) already stopped"
exit 0
fi
kill -TERM $(print_process)
echo -ne "Waiting for process to stop"
NOT_KILLED=1
for i in {1..20}; do
if check_if_process_is_running
then
echo -ne "."
sleep 1
else
NOT_KILLED=0
fi
done
echo
if [ $NOT_KILLED = 1 ]
then
echo "Cannot kill process $(print_process)"
exit 1
fi
echo "Process stopped"
;;
start)
if [ -f $PIDFile ] && check_if_process_is_running
then
echo "Process $(print_process) already running"
exit 1
fi
nohup java $SPRING_OPTS -jar $JARFile &
echo "Process started"
;;
restart)
$0 stop
if [ $? = 1 ]
then
exit 1
fi
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
esac
exit 0
I'm sure that there are a lot of possibilities to tune that script, so comments are welcomed :)
Published at DZone with permission of Jakub Kubrynski, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Octavian Covalschi replied on Fri, 2014/05/09 - 1:28pm

 I'm not sure that "uber jar" is accurate for spring boot. We're using gradle to build  a few spring boot apps and distZip is zipping 2 dirs bin and lib. Lib contains all dependencies as separate jars.

Jakub Kubrynski replied on Fri, 2014/05/09 - 1:41pm in response to: Octavian Covalschi

Normally by gradle plugin you have one jar file, which contains all project classes, META-INF, properties, etc and also lib subdirectory on root level containing all dependencies jars. It's called "uber jar"

Octavian Covalschi replied on Fri, 2014/05/09 - 2:20pm in response to: Jakub Kubrynski

 Yes, that's what I said, you have a separate lib directory, that contains all dependencies and they all are separate jar files and not included in one, big, fat, uber jar... All spring related jars are outside the main app's jar. So, there is no uber jar here IMHO.

Jakub Kubrynski replied on Fri, 2014/05/09 - 3:01pm in response to: Octavian Covalschi

There is - "uber jar" is just a jar file containing both - your classes and dependencies. There is nothing about if dependencies should be exploded or not

Don Laidlaw replied on Tue, 2014/05/13 - 7:38am

With the nohup command you should redirect stdout and stderr so that program output does not end up in a file named nohup.out in the current directory, or in the HOME directory if the current directory is not writeable. So the nohup becomes:

view sourceprint?1.

nohup java $SPRING_OPTS -jar $JARFile >/dev/null 2>&1 &

Lucas Mauricio ... replied on Fri, 2014/05/16 - 10:10pm

hi Jakub Kubrynski,

I'm stucked in a previous step: what is the jar for the class ApplicationPidListener?

regards

Jakub Kubrynski replied on Sat, 2014/05/17 - 12:12pm in response to: Lucas Mauricio C. E Martins

Hi Lukas - ApplicationPidListener is included in spring-boot-starter-actuator

Jakub Kubrynski replied on Sat, 2014/05/17 - 12:53pm in response to: Don Laidlaw

@Don - I'm not sure it's the best solution, because in this case we'll lose some kinds of errors, including all before starting application.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.