spring boot init.d script start-stop-daemon: unrecognized option --no-close - java

after symlink my app to the /etc/init.d/myappname.
/etc/init.d/myappname start gives "Failed to start"
/var/log/appname.log tells
"start-stop-daemon: unrecognized option '--no-close'"
when i remove the --no-close, the jar becomes corrupted and cannot run anymore. i am struck.
bdw my jar is fullyexecutable jar. i.e., when i run the jar alone it starts up the springboot normally.
whats going wrong here?
EDIT:
do_start() {
working_dir=$(dirname "$jarfile")
pushd "$working_dir" > /dev/null
if [[ -n "$run_user" ]]; then
mkdir "$PID_FOLDER" &> /dev/null
checkPermissions || return $?
chown "$run_user" "$PID_FOLDER"
chown "$run_user" "$pid_file"
chown "$run_user" "$log_file"
if [ $USE_START_STOP_DAEMON = true ] && type start-stop-daemon > /dev/null 2>&1; then
arguments=(-Dsun.misc.URLClassPath.disableJarChecking=true $JAVA_OPTS -jar $jarfile $RUN_ARGS "$#")
start-stop-daemon --start --quiet \
--chuid "$run_user" \
--name "$identity" \
--make-pidfile --pidfile "$pid_file" \
--background --no-close \
--startas "$javaexe" \
--chdir "$working_dir" \
-- "${arguments[#]}" \
>> "$log_file" 2>&1
await_file "$pid_file"
else
su -s /bin/sh -c "$command >> \"$log_file\" 2>&1 & echo \$!" "$run_user" > "$pid_file"
fi
pid=$(cat "$pid_file")
else
checkPermissions || return $?
$command >> "$log_file" 2>&1 &
pid=$!
disown $pid
echo "$pid" > "$pid_file"
fi
[[ -z $pid ]] && { echoRed "Failed to start"; return 1; }
echoGreen "Started [$pid]"
}

I assume you already created an executable JAR of your Spring Boot app.
Copy your app to /var/appname/appname.jar
Make sure it's given execute permission:
sudo chmod +x "/var/appname/appname.jar"
Create a config file /var/appname/appname.conf with the following content
USE_START_STOP_DAEMON=false
Follow instructions from Spring Boot Reference Guide
To install a Spring Boot application as an init.d service simply create a symlink:
$ sudo ln -s /var/appname/appname.jar /etc/init.d/appname
Once installed, you can start and stop the service in the usual way. For example, on a Debian based system:
$ service appname start

i finally solve this problem.
--no-close is a parameter that was "recently" added to start-stop-daemon
http://manpages.ubuntu.com/manpages/wily/man8/start-stop-daemon.8.html
I run my app.jar on Ubuntu 12.04 LTS that has
start-stop-daemon 1.16.1.2 for Debian
You could know what version you are running using:
start-stop-daemon --version
on linux console.
I downloaded a newer version of start-stop-daemon on
https://pkgs.org/ubuntu-14.04/ubuntu-main-amd64/dpkg_1.17.5ubuntu5_amd64.deb.html
Install the deb package and spring boot jar will finally run.

Run "service myappname start" as mentioned in the document http://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html
There is a difference between /etc/init.d/myappname start and server myappname start

Related

Spring Boot and GraalVM native-image

With the latest releases of Spring Boot 2.3.0, spring-graalvm-native 0.7.0.BUILD-SNAPSHOT, GraalVM 20.1.0.r11 and the corresponding blog posts
https://spring.io/blog/2020/04/16/spring-tips-the-graalvm-native-image-builder-feature
https://blog.codecentric.de/en/2020/05/spring-boot-graalvm
I also started to play around with one of my apps.
Luckily I was able to compile my app without any big hurdles. My compile.sh script looks as follows
#!/usr/bin/env bash
echo "[-->] Detect artifactId from pom.xml"
ARTIFACT=$(mvn -q \
-Dexec.executable=echo \
-Dexec.args='${project.artifactId}' \
--non-recursive \
exec:exec);
echo "artifactId is '$ARTIFACT'"
echo "[-->] Detect artifact version from pom.xml"
VERSION=$(mvn -q \
-Dexec.executable=echo \
-Dexec.args='${project.version}' \
--non-recursive \
exec:exec);
echo "artifact version is '$VERSION'"
echo "[-->] Detect Spring Boot Main class ('start-class') from pom.xml"
MAINCLASS=$(mvn -q \
-Dexec.executable=echo \
-Dexec.args='${start-class}' \
--non-recursive \
exec:exec);
echo "Spring Boot Main class ('start-class') is '$MAINCLASS'"
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m'
echo "[-->] Cleaning target directory & creating new one"
rm -rf target
mkdir -p target/native-image
echo "Packaging $ARTIFACT with Maven"
mvn -ntp package > target/native-image/output.txt
echo "[-->] Expanding the Spring Boot fat jar"
JAR="$ARTIFACT-$VERSION.jar"
rm -f $ARTIFACT
echo "Unpacking $JAR"
cd target/native-image
jar -xvf ../$JAR >/dev/null 2>&1
cp -R META-INF BOOT-INF/classes
LIBPATH=`find BOOT-INF/lib | tr '\n' ':'`
CP=BOOT-INF/classes:$LIBPATH
GRAALVM_VERSION=`native-image --version`
echo "Compiling $ARTIFACT with $GRAALVM_VERSION"
{ time native-image \
--verbose \
--no-server \
--no-fallback \
--enable-all-security-services \
-H:Name=$ARTIFACT \
-Dspring.native.remove-unused-autoconfig=true \
-Dspring.native.remove-yaml-support=true \
-Dspring.native.remove-xml-support=true \
-Dspring.native.remove-spel-support=true \
-Dspring.native.remove-jmx-support=true \
-cp $CP $MAINCLASS >> output.txt ; } 2>> output.txt
if [[ -f $ARTIFACT ]]
then
printf "${GREEN}SUCCESS${NC}\n"
mv ./$ARTIFACT ..
exit 0
else
cat output.txt
printf "${RED}FAILURE${NC}: an error occurred when compiling the native-image.\n"
exit 1
fi
But now my troubles start: My app relies on some CSVs during startup to load data.
The data is loaded like this
InputStream is = CSVUtil.class.getResourceAsStream("/myData.csv");
The file is present at /src/main/resources/myData.csv
As said the compilation works without an issue but once I start the app it can't find the CSV.
Caused by: java.lang.NullPointerException: null
at java.io.Reader.<init>(Reader.java:167) ~[na:na]
at java.io.InputStreamReader.<init>(InputStreamReader.java:113) ~[na:na]
at ch.aaap.raw.CSVUtil.getData(CSVUtil.java:33) ~[na:na]
...
It seems that it's not part of the compilation. Any hints how I can make the native-image command aware about the fact that I need these CSVs?
Looks like adding following argument helps
-H:IncludeResources='.*/*.csv$'

Logs stucks when deployment is done through teamcity

Recently we migrated to Teamcity deployment from manual process. Ours is java application on linux server.
Whenever deployment is done through Teamcity, logs are stuck i.e. after shutdown log messages nothing else is printed in the logs. Then we run manual stop and start scripts on the server to get the logs running.
Looks like somehow Teamcity locks log file and doesn't release it.
How to overcome it?
In Teamcity, deploy step is defined as below:
REMOTE_PATH="/opt/app/$ARTIFACT/releases/teamcity"
cd $TEAMCITY_REPO_HOME/$ARTIFACT/build/libs
echo "Uploading artifact"
ssh $UAT_HOST -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "mkdir -p $REMOTE_PATH"
scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $ARTIFACT.jar $UAT_HOST:$REMOTE_PATH
echo "Stopping service"
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $UAT_HOST "sh /opt/app/$ARTIFACT/stop.sh"
sleep 3s
echo "Copying new artifact"
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $UAT_HOST "cp $REMOTE_PATH/$ARTIFACT.jar /opt/app/$ARTIFACT"
sleep 6s
echo "Starting service"
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $UAT_HOST "sh /opt/app/$ARTIFACT/start.sh"
Taking ideas from above comments of Andy Dufresne, I created one deploy script as below:
This single script stops server, takes backup of current artifact, copies new build and then executes start script to start the server.
#!/bin/bash
#check for correct number of arguments
if [ "$#" -ne 1 ]; then
echo "Incorrect number of arguments, exiting..."
exit 1
fi
ARTIFACT=$1
cd "/opt/app/$ARTIFACT"
echo $(pwd)
echo "Stopping service"
bash stop.sh
sleep 3s
echo "Tagging artifact with release"
cp "releases/teamcity/$ARTIFACT.jar" "releases/teamcity/$ARTIFACT`date +'_%y_%m_%d'`.jar"
echo "Deleting old releases"
cd "releases/teamcity" && \
ls | grep -v '/$' | head -n -6 | xargs -d '\n' -r rm -- && \
cd "/opt/app/$ARTIFACT" && \
ls -l "releases/teamcity"
echo "Copying new artifact"
cp "releases/teamcity/$ARTIFACT.jar" .
echo "Starting service"
bash start.sh
sleep 2s
This script is called from team-city in its build steps(previously stopping server, copying artifact and starting server all were done by teamcity explicitly as outlined in the question.)
Now teamcity build step looks concise as under and WORKS as expected(that important !!!):
REMOTE_PATH="/opt/app/$ARTIFACT/releases/teamcity"
cd $TEAMCITY_REPO_HOME/$ARTIFACT/build/libs
echo "Uploading artifact"
ssh -o "StrictHostKeyChecking=no" "$UAT_HOST" "mkdir -p $REMOTE_PATH"
scp -o "StrictHostKeyChecking=no" "$ARTIFACT.jar" "$UAT_HOST:$REMOTE_PATH"
echo "Deploying artifact"
ssh -o "StrictHostKeyChecking=no" "$UAT_HOST" "sh /opt/app/$ARTIFACT/deploy.sh $ARTIFACT"

Unable to stop java process using SIGINT on Linux

I am building a virtual machine for some tests that needs to run among other things DynamoDb web service. VM is based on stock Ubuntu 16.04 64bit.
This is the part of provisioning script that installs DynamoDB:
# Install local instance of DynamoDB
DARCHFILE='/tmp/dynamodb_local_latest.zip'
wget -P /tmp/ -nv https://s3-us-west-2.amazonaws.com/dynamodb-local/dynamodb_local_latest.zip
sudo unzip -q "$DARCHFILE" -d /usr/local/lib/dynamodb
sudo mkdir -pv /var/lib/dynamodb/
sudo mkdir -pv /var/log/dynamodb/
sudo apt-get install -y openjdk-8-jdk
This is the script that executes DynamoDb:
#!/bin/bash
# -*- mode: sh -*-
# vi: set ft=sh :
java -Djava.library.path=/usr/local/lib/dynamodb/DynamoDBLocal_lib/ \
-jar /usr/local/lib/dynamodb/DynamoDBLocal.jar \
-dbPath /var/lib/dynamodb/ \
-optimizeDbBeforeStartup \
-port 8000 > /var/log/dynamodb/trace.log 2> /var/log/dynamodb/error.log &
echo $! > /var/run/dynamodb.pid
Now if I try to stop the process using the "nice one" SIGINT (equivalent of Ctrl+C) it does nothing. Only sending SIGTERM works.
So this does nothing:
sudo kill -s SIGINT $(< /var/run/dynamodb.pid)
As we can confirm by executing this:
sudo ps -x | grep $(< /var/run/dynamodb.pid)
While this works just fine:
sudo kill -s SIGTERM $(< /var/run/dynamodb.pid)
On the other hand if I start dynamodb manually and don't send it to the background Ctrl+C does work.
So what gives? Is it my mistake or behavior by design?
Thanks

run java project using .sh file in jenkins in mac

i want to run a java project in jenkins in mac.i have the following .sh file and its code is given below:
#!/bin/bash
echo $#
${jvmargs[#]}
DIR=$(dirname $0)
args=( "$#" )
javaProps=( )
server_jvmargs=( -Djava.awt.headless=true -Xms1024m -Xmx1024m"${jvmargs[#]}" )
XX_HOME="$DIR"
client_classpath="$XX_HOME/lib/others/*:$XX_HOME/lib/http/*:$XX_HOME/lib/selenium-java-2.37.0/*:$XX_HOME/lib/selenium-java-2.37.0/libs/*:$XX_HOME/lib/TestNG/*:$XX_HOME/lib/mailactivation/*:$XX_HOME/bin"
BIN_PATH="$XX_HOME/bin"
SRC_PATH="$XX_HOME/src"
rm -rfv "$BIN_PATH"
chmod 777 "$BIN_PATH"
mkdir -p "$BIN_PATH"
cd $DIR
javac \
-cp "$client_classpath" \
-d "$BIN_PATH" \
-sourcepath $SRC_PATH src/com/*.java
java \
"${server_jvmargs[#]}" \
"${javaProps[#]}" \
-Dxx.home="$XX_HOME" \
-Duser.dir="$XX_HOME" \
-cp "$client_classpath" \
org.testng.TestNG temp-testng-customsuite.xml
i set the custom workspace and use this run.sh file in build setup(Execute Shell). But it shows the following error:
Started by user Ali Azam JenkinTest
Building in workspace /Users/aliazam/Desktop/App/eclipse/workspace/Training
java.io.IOException: Failed to mkdirs: /Users/aliazam/Desktop/App/eclipse/workspace/Training
at hudson.FilePath.mkdirs(FilePath.java:1164)
at hudson.model.AbstractProject.checkout(AbstractProject.java:1268)
at hudson.model.AbstractBuild$AbstractBuildExecution.defaultCheckout(AbstractBuild. java:610)
at jenkins.scm.SCMCheckoutStrategy.checkout(SCMCheckoutStrategy.java:86)
at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:532)
at hudson.model.Run.execute(Run.java:1741)
at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
at hudson.model.ResourceController.execute(ResourceController.java:98)
at hudson.model.Executor.run(Executor.java:410)
Finished: FAILURE
can anyone please help me to solve this problem????

Tomcat start and stop using shell script?

I have below shell script to stop/stop the tomcat.
#!/bin/bash
export BASE=/home/programs/jakarta-tomcat-5.0.28/bin
prog=jakarta-tomcat-5.0.28
stat() {
if [ `ps auxwwww|grep $prog|grep -v grep|wc -l` -gt 0 ]
then
echo Tomcat is running.
else
echo Tomcat is not running.
fi
}
case "$1" in
start)
if [ `ps auxwwww|grep $prog|grep -v grep|wc -l` -gt 0 ]
then
echo Tomcat seems to be running. Use the restart option.
else
$BASE/startup.sh 2>&1 > /dev/null
fi
stat
;;
stop)
$BASE/shutdown.sh 2>&1 > /dev/null
if [ `ps auxwwww|grep $prog|grep -v grep|wc -l` -gt 0 ]
then
for pid in `ps auxwww|grep $prog|grep -v grep|tr -s ' '|cut -d ' ' -f2`
do
kill -9 $pid 2>&1 > /dev/null
done
fi
stat
;;
restart)
if [ `ps auxwwww|grep $prog|grep -v grep|wc -l` -gt 0 ]
then
for pid in `ps auxwww|grep $prog|grep -v grep|tr -s ' '|cut -d ' ' -f2`
do
kill -9 $pid 2>&1 > /dev/null
done
fi
$BASE/startup.sh 2>&1 > /dev/null
stat
;;
status)
stat
;;
*)
echo "Usage: tomcat start|stop|restart|status"
esac
Now above script works with local tomcat. Now how can i modify above script to stop/start remote tomcat?
Thanks!
You could use ssh to execute a local script on the remote machine to start/stop Tomcat, so if you are in a linux terminal, you could do something like:
ssh username#remoteMachine /home/username/myScipts/start_tomcat.sh
where start_tomcat.sh would be a script in the remote machine, of course you would need a valid username/password on the remote machine, and also the remote machine would need to have sshd installed and running

Categories