Unable to run java jar command on target machine in Ansible - java

I am trying to run the following command:
java -jar jar-from-application.jar --file myown.properties
Couple of problems I faced earlier while trying to run this on target machine. Tomcat needs to be running and a war file needs to be deployed completely before I run the above command. This is what I did to insure that pre conditions are met. For Tomcat:
nohup startup.sh
and then check for deployed file bu using curl to check for status 200:
- name: Check if URL is available
shell: curl --head --silent http://target-mchine:8080/restoftheurl
register: result
until: result.stdout.find("200 OK") != -1
retries: 12
delay: 10
It does above two steps correctly but when the next task is to run the
java -jar jar-from-application.jar --file myown.properties
it for some reason says that it cannot read the properties file. However, if I run the same jar command on the remote machine locally, then it works perfectly. I even added some wait time after successful execution of curl command, just in case, but it doesn't make any difference. I tried doing the following too:
nohup java -jar jar-from-application.jar --file myown.properties
as it was suggested online but that didn't make any difference either. Any suggestions will be appreciated. Thank You.

Make sure that you set the correct path to the properties file in the command by using the chdir argument of the command module or set the full path in the command.

Related

How to automatically start 2 Java jars on AWS EC2?

I'm learning to deploy Spring Boot apps on AWS EC2. And I know how to automate app launch, when I start the EC2 instance, I don't need to manually use the command java -jar java-service.jar, I just add this command in the /etc/rc.local file and that is all. But I have 2 microservice, and I want to start both of them automatically, but if I try to add both commands in the /etc/rc.local it's not working, only the first service will start, the second service will not start.
So I have the commands added like this:
And after I start the EC2 instance only the first service is started:
Thank you!
I am not a unix expert, but I see the only issue in running 2 java commands from terminal is that unless the first command returns, the next command is not executed. So, I think the solution would be run the 1st command in some interactive mode so that the other commands can be executed simultaneously.
There are ways in unix shell to run a command in background. I found this useful link - https://www.maketecheasier.com/run-bash-commands-background-linux/
In bash terminal, a command can be made to run in background by appending it with &. So, I think you should be able to start both jars if you do something like -
java -jar /home/ec2-user/first.jar &
java -jar /home/ec2-user/second.jar
I recommend to use Systemd.
Create a Systemd unit file for every microservice, save it in /etc/systemd/system/my-app.service. Something like that:
[Unit]
Description=My Java app
After=syslog.target network.target
[Service]
EnvironmentFile=/etc/sysconfig/my-app-env
WorkingDirectory=/my/app/home
ExecStart=/usr/bin/java $JAVA_OPTS -jar my-app.jar
KillMode=process
User=my-app-user
Restart=on-failure
[Install]
WantedBy=multi-user.target
Then, run:
systemctl daemon-reload
systemctl enable --now my-app
After that, you can use:
systemctl status my-app
systemctl stop my-app
systemctl start my-app
Another solution is to bundle your jars into Docker images. This of course requires Docker runtime and adds an overhead, but it also has some benefits:
Complete separation of jar files. Easily use different java versions.
No need to worry about differences of local and ec2 environment.
Easily scale to 3 or more jars.
Use Docker Cli to build and start containers. Works great in a Devops Pipeline.
You can read here to learn how to create Spring Boot Docker images. After you build an image. You start it like this.:
docker run -p 8080:8080 springio/gs-spring-boot-docker
You can run as many docker run commands you need, one after another.
I am not sure which system you are using in starting application:
For linux base system, you can use crontab to schedule the task when the server reboot.
Follow this steps:
Download crontab
#apt-get install cron
Edit the file file to enable the task
crontab -e
(Choose Vim or nano to edit the task)
Add this code to your server
#reboot /usr/bin/java -jar XXXXX.jar
Save your file
Check the result
crontab -l
#systemctl status cron
This method works in my Debian system. For more details, you can refer to
How to automatically run program on Linux startup
If you are running from bash, then join two jar commands with "&" like below.
java -jar /home/ec2-user/first.jar&java -jar /home/ec2-user/second.jar
coupon service
Run the command 'java -jar /home/ec2-user/coupon-service-0.0.1-SNAPSHOT.JAR'
Press CTRL+Z, type bg, press Enter, type disown, press Enter.
product service
Run the command 'java -jar /home/ec2-user/product-service-0.0.1-SNAPSHOT.JAR'
Press CTRL+Z, type bg, press Enter, type disown, press Enter.
NOTE: Both services should have different ports.

Apache airflow task: java: command not found

I'm running Apache Airflow using Docker. I have installed OpenJDK12 and defined its variables in both of:
~/.bachrc
/usr/local/airflow/.bachrc
export JAVA_HOME=/usr/local/src/jdk-12
export PATH=$PATH:$JAVA_HOME/bin
and I can see Java is running normally especially when I run the Task from the command line :
airflow test ip-importer Download 2020-2-19
where it's working properly without errors , where the task is for :
Executing java command to run a Jar file
But now when I schedule the task on the webserver UI and when I run it, It doesn't run properly and gives me this error:
[2020-02-18 00:46:39,941] {{bash_operator.py:126}} INFO -
/tmp/airflowtmpdzijcupu/Download886rmbol: line 1: java: command not
found
so seems like It's unable to see the defined paths for Java.
Any hints / ideas for how to solve this issue ?
Another question , In case if the java application has thrown an exception/error , Airflow doesn't assume it as an error , it assumes it as a succeeded task , Could you advise how to enforce airflow to assume the exception as a real interrupter for the task ?
Check if /usr/bin folder from Docker container has the executable file pointing out to Java cmd. If not, create one with the following cmd:
Example:
ln -s /usr/local/airflow/java/jdk1.8.0_161-x64/bin/java /usr/bin/java

Bash script behaves differently from Docker run command instead of inside container itself?

I am running the Docker 1.0.1 client on Ubuntu 12.0.4 LTS. I have a container that runs a Java application in server mode. There is a Bash script in the container that launches the server. If I execute the bash script from inside the container's the Java application runs fine. If I append the bash script to the end of the Docker run command and try to launch it that way, the run fails. Checking the logs I see an error indicating the main class for the Java app could not be found.
Here's the command line:
$> sudo docker run -p 1566:1566 -d $USER/server /server_install/run-server.sh
If I remove /server_install/run-server.sh from the command line, the container launches fine and stays resident. But with the script file in the command line the container terminates and the logs show the error message that indicates the main Java class could not be found. However, if I enter the container and launch run-server.sh from within the /server_install directory, it works fine.
Do paths behave differently from inside a container's Bash shell then they do when you launch something from the command line? Or do I have to change the current working directory to /server_install before executing the Bash script. If so how do I do that? That seems a little weird because the run-server.sh script sets up the Java path options inside of it.
Or do I have to change the current working directory to /server_install before executing the Bash script. If so how do I do that?
Use the WORKDIR directive in your Dockerfile.
My guess is whatever script sets your CLASSPATH takes the current working directory into consideration.

How to properly start a script generated by gradle using upstart?

I'm trying to deploy an Java app onto VPS. I'm using Gradle build system with 'application' plugin. I want the app to start up with the server.
During deployment process I run ./gradlew install to prepare run scripts. When ran directly, they work properly.
I used http://www.whiteboardcoder.com/2014/02/ubuntu-upstart-job-with-java-jar.html as a base for upstart configuration:
description "the test server"
start on runlevel [2345]
stop on runlevel [!2345]
expect fork
script
cd /opt/testserver/
exec ./build/install/testserver/bin/testserver
end script
But the PID reported by upstart after running start testserver is different then the one found using ps. My guess is that the reason for that is the last line of generated script:
exec "$JAVACMD" "${JVM_OPTS[#]}" -classpath "$CLASSPATH" mypackage.TestServer"$#"
As a result Upstart is not able to stop the app. Is there a way to make upstart see the right PID?
Well it looks like there is no forking going on here, so you should try removing the expect fork bit.

Linux Launch java program on startup (EC2 instance)

my server program needs to be launched on the startup of an EC2 instance. At the minute im just launching it from my SSH with the following commands:
java -jar ~/DocumentManager/DocumentServer-0.2.jar
I tried adding this to the .bashrc and /etc/rc.local files but they only seem to work when i ssh in.
Anyone know how to make it so an instance of my application is launched when the computer boots?
Thanks,
Ben
It's possible you can create a script java_server_launch.sh like this:
#! /usr/bin/sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
JAVA=/usr/bin/java
MY_SERVER=/home/your_username/DocumentManager/DocumentServer-0.2.jar
USER=your_username
/bin/su - $USER -c "$JAVA -jar $MY_SERVER &"
Put your script under /etc/init.d directory, and then use the command:
update-rc.d java_server_launch.sh defaults
more on update-rc.d command by using man update-rc.d.
Hope this help.
Regards.
Add ampersand(symbol '&') at the end of the command.
For example, in your case, java -jar ~/DocumentManager/DocumentServer-0.2.jar &
Old question, but my answer might be helpful for people who look in future.
You can also run your program as a service which automatically run on ec2 container reboot. Below link worked for me:
https://medium.com/#lizlieholleza/run-your-java-application-as-a-service-in-an-ec2-instance-amazon-linux-d7c7b4c0b2f4

Categories

Resources