SSH command can not start remote java process - java

I have a start function, and I put it in a script resides on a remote site, the function's code shows below.
function start() {
cd $install_dir
mkdir -p logs
export classpath=$classpath:$target_jar
nohup java -Xms2048m -Xmx8192m -server -XX:PermSize=128m -XX:MaxPermSize=256m \
-XX:+PrintGCDetails -XX:+PrintGCDateStamps \
-XX:-OmitStackTraceInFastThrow \
-cp $target_jar $main_class >> logs/jvm.log 2>&1 &
echo "Service started, see logs"
}
And when I try to call that function use ssh ssh xxx#host "./service.sh start", I can not start the java process, I only got the response message "Service started, see logs" and there's no error, the jvm.log is also empty. It apparently to me that my script has executed, but the target java process didn't run.
If I logon to that remote site, and execute ./service.sh start, it works.

Since you were able to run the service manually, the ssh and script part is fine.
What could go wrong is the environment. For example you referred java without absolute path. Hence your may be running a different version of it. It is also possible that variable for shared library loading (LD_LIBRARY_PATH) are having different values.
Finally check for file permissins

Related

How to set environment variables so they work in non-interactive bash shells?

I am running the amazonlinux:2 docker image directly from dockerhub and installing the corretto-17 JDK with the following command:
yum install -y git java-17-amazon-corretto-devel
Note: I am not using a custom Dockerfile, I do not control it and I can't change it.
When I then try and run my .gradlew task, it fails because there's no JAVA_HOME set.
So I do that by:
echo "export JAVA_HOME='/usr/lib/jvm/java-17-amazon-corretto.x86_64'" >> /root/.bashrc
If I manually connect a terminal to to the container, the .bashrc works fine and gradlew will run.
But when I run commands from outside the container via something like:
docker exec kopibuild /bin/bash -c "cd the-project-code && ./gradlew build"
The .bashrc is not loaded so JAVA_HOME is not set and gradlew fails.
My workaround is to add the interactive flag -i to the bash command and then it all works, but there are warnings in the logs about "cannot set terminal process group (-1): Inappropriate ioctl for device".
docker exec kopibuild /bin/bash -c "cd the-project-code && BASH_ENV=/root/.bashrc ./gradlew build"
But it didn't seem to do anything.
What's the right way to set environment variables for Amazon Linux so they will exist in non-interactive shell invocations?
After digging around on the Googles - I believe there is no standard Linux way to set an environment variable for non-interactive shells.
But there is a Docker way to answer the question. On the original docker create of the container from the amazonlinux:2 image, specify the environment variable via -e JAVA_HOME=/usr/lib/jvm/java-17-amazon-corretto.x86_64. This stores the environment variable in the docker metadata for the container and it will be available in all execution contexts, including non-interactive shells invoked directly via docker exec (without having to specify it explicitly for every exec command).
As far as I know, this is the same as what the ENV command in a Dockerfile does.

Ansible terminates my app with "nohup"

I have a task in Ansible playbook that executes a .jar file in the background, but after finishing that task, the (java) app terminates.
- name: Run Java app in the background
shell: nohup java -jar app.jar &
I need the app running for tasks further down in the playbook. Any ideas??
NOTE: When I run it in Putty ssh session it runs smoothly and the app stays in background.
The most likely reason is attached IO. Try:
- name: Run Java app in the background
shell: nohup java -jar app.jar </dev/null >/dev/null 2>&1 &
Ok So I had this issue today and my script is a tad different but essentially doing the same thing so this is what I have, running on Oracle, Centos and RHEL.
in script start_service.sh I have this, this script is executed not sourced.
#!/bin/sh
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)"
nohup java -jar ${DIR}/$1 --spring.config.location=${DIR}/application.yml --logging.config=${DIR}/logging.xml > ${DIR}/log/output.log 2>&1 &
In my playbook I have:
- name: run service
shell: "{{ service_install_location }}/application_name/start-service.sh application_name-{{ application_version }}.jar"
args:
chdir: "{{ service_install_location }}/application_name"
executable: /bin/bash
Now, the BASH_SOURCE argument is specific to bash so if you are running plain old sh then you need $0. nohup is required so when the ssh connection terminates your background task does not get killed (turn on -vvv for ansible to see connections being made to understand how this happens on a remote machine).
I should point out we are doing this temporarily as this should really be installed as a service to be under the control of service/init.d but for now, this answers your question

Log output shows in Jenkins while running bash script to execute Java code

At first let me describe my issue.
I configured Jenkins and after build action I called shell script to run bash script on remote server.
The shell script starts application via command
java -Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=xxx
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-XX:+HeapDumpOnOutOfMemoryError -jar name.jar "BUILD_PARAMETER"
I see logs from my application in Jenkins build, and it's keep build process running. I need to finish it after running
sh run command. Is it possible?
If you're doing this using Jenkins you will need to use the nohup notation as in the comments as well as specifying a non-numerial PID for the process. Jenkins tries to clean up after a job finishes by killing any processes it starts.
BUILD_ID=dontKillMe nohup <-your command -> &
the above command should work
https://wiki.jenkins-ci.org/display/JENKINS/Spawning+processes+from+build
Your shell script need to fork a process, and return, otherwise Jenkins thinks your shell script is still running (which it is, if it's not forking the process and returning).
You have not provided the command you use to launch your application, but a common way to fork a process in linux is:
nohup <your command here> &

Run java application as background process via ssh

I'm currently developing a simple deployment script for vms running ubuntu.
All these machines are supposed to run a java application provided as a jar.
This is the relevant part of the script installing java, copying a jar from local machine to remote machine and then starting the application:
ssh ubuntu#$line -i ~/.ssh/key.pem -o StrictHostKeyChecking=no <java_installation.sh
scp -i ~/.ssh/key.pem $JARFILE ubuntu#$line:~/storagenode.jar
ssh ubuntu#$line -i ~/.ssh/key.pem <java_start_jar.sh
the installation via the java_installation.sh script succeeds, the scp command does as well.
The problem occurs when trying to execute the commands in java_start_jar.sh via ssh.
java_start_jar.sh:
#!/bin/sh
# this script starts a jar file and creates a shellscript which can be used to stop the execution.
nohup java -jar ~/storagenode.jar & > ~/storagenode.log
pId=$!
echo "kill $pId" > ~/stop_storagenode.sh
chmod u+x ~/stop_storagenode.sh
The scripts starts the execution of the .jar file, but then simply blocks.
Ssh does not return, the rest of the local code is only executed after manually closing connection.
Any ideas why the java application is not properly running as a background process?
Move the & to the end of the line
#!/bin/sh
# this script starts a jar file and creates a shellscript which can be used to stop the execution.
nohup java -jar ~/storagenode.jar > ~/storagenode.log &
pId=$!
echo "kill $pId" > ~/stop_storagenode.sh
chmod u+x ~/stop_storagenode.sh

Reboot Java Application with Linux

What would be a solution to rebooting a java application with linux instead of using
"sh run.sh"
in terminal whenever I want to reboot it? The run.sh contains this:
java -Xmx1024m -Xss2m -Dsun.java2d.noddraw=true -XX:+DisableExplicitGC -XX:+AggressiveOpts -XX:+UseAdaptiveGCBoundary -XX:MaxGCPauseMillis=500 -XX:SurvivorRatio=16 -XX:+UseParallelGC -classpath bin:data/libs/* com.runeown.Application
I want to restart it using terminal.
If you do not want to restart it using "sh run.sh" and instead you want to restart it using a command, you could use a bash alias to run the command.
here is the manual (http://www.ss64.com/bash/alias.html)
here is a relevant askubuntu thread about making a permanent alias (https://askubuntu.com/questions/17536/how-do-i-create-a-permanent-bash-alias)
An alias is essentially a shortcut for the terminal, for instance you had a dropbox folder located at ~/myfiles/1/2/dropbox and you did not want to type cd + path every time, you could make an alias:
alias cddropbox="cd ~/myfiles/1/2/dropbox"

Categories