Jenkins CI: Switching server program jars at build.

The aim

I'm working on Java/Scala project that is deployed as jar file. What I want to do is: When a push is made to github, I want Jenkins to replace the old jar by new jar and launch a new processes from the new jar. In that way, there is no more worries about human error. Note that this is my way of doing it, there should be better way.

Step 1: Installing daemonize

If you spawn a new process from Jenkins post build shell, the build won't finish AFAIK. This happens because Jenkins always wait for child processes to be completed, thus, never ending story. To avoid Jenkins to hung up, we want to daemonize the process as we launches it; hence we need a daemonize command.

 yum install daemonize 

To Daemonize command properly, the daemonize command should be called from root user. Now we add jenkins to sudoers to achive it.

 /etc/sudoers
 jenkins ALL=(ALL)       NOPASSWD:ALL

Note that full path is required for any arguments when you call daemonize command.

Step 2: Killing the old processes

On Jenkins post build action, let Jenkins kill the old processes before launching from new jar. Suppose that jar file name is JarOfHearts.jar. Following bash compatible shellscript kills the processes launched from JarOfHearts.jar.

#!/bin/bash
# Extracting process ids from ps x dump
PIDS=($(sudo ps x | grep -v grep | grep -oP "JarOfHearts.jar" | grep -oP "^\s*[1-9]+[0-9]*" | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g'))
# Killing bastards
for pid in ${PIDS[@]}
do
 echo killing $pid ...
 sudo kill -9 $pid
done
Step 3: Launching new processes from brand new jar.

Finally, launching server programs from the new jar. In this senario, we redirect stdout to /var/log/server.log and stderr to /var/log/server.error.log.

sudo daemonize -o /var/log/$BUILD_NUMBER.server.log -e /var/log/$BUILD_NUMBER.server.error.log /usr/bin/java -classpath /path/to/JarOfHearts.jar main.Main Argument1 Argument2 ...  

End Product

#!/bin/bash
# Extracting process ids from ps x dump
PIDS=($(sudo ps x | grep -v grep | grep -oP "JarOfHearts.jar" | grep -oP "^\s*[1-9]+[0-9]*" | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g'))
# Killing bastards
for pid in ${PIDS[@]}
do
 echo killing $pid ...
 sudo kill -9 $pid
done

echo Assembling jar ...
sbt clean assembly

echo Launching server from new jar ...
sudo daemonize -o /var/log/$BUILD_NUMBER.server.log -e /var/log/$BUILD_NUMBER.server.error.log /usr/bin/java -classpath /path/to/JarOfHearts.jar main.Main Argument1 Argument2 ...  

peace.