Spring not seen environment variables from systemd service - java

I'm trying to run spring boot app with systemd service of ubuntu.
In my service file, I have ExecStart variable
ExecStart=/bla/run.sh
And variables:
Environment="DB_HOSTNAME=ip"
Environment="DB_PORT=5432"
...
(I have tried both variants: with and without braces)
My sh file looks like:
#!/bin/sh
echo jdbc:postgresql://${DB_HOSTNAME}:${DB_PORT}/${DB_NAME}
sudo /usr/bin/java -jar bla.jar
Inside sh variables are available as well, but spring application does not deal with them. The same with the active profile variable.
I thought that the problem is about the scope of variables and I tried to pass them to another sh from the main one. But in another script they are available, so the problem only with spring app.
Update
Trick with export does not help

Maybe it will helpful for somebody.
The main problem was using sudo for starting java app.
After removing sudo variables become available.

Related

Pass environment variable on AWS Elastic Beanstalk for Spring Boot App using Jasypt

I was deploying my Spring Boot Application on AWS Elastic Beanstalk. My web app is using Jasypt, so in the application.properties file, I wrote down jasypt.encryptor.password=, currently the password in this file is empty, I want to pass the password as a variable on AWS Beanstalk's configuration.
When testing locally, I used java -jar myapp.jar --jasypt.encryptor.password=1234 in command line, and it ran successfully. However, when deploying on AWS, I added jasypt.encryptor.password in environment properties and set its value to 1234, the app failed to run. The log said I cannot set the password as empty. So, at this point Beanstalk did not read the environment property I just set. But it can really read the properties later because I tested it after setting another property and used GET API to print it.
My question is: how to make Elastic Beanstalk run/read the environment properties at the beginning? In other words, how to make EB run java -jar myapp.jar with --jasypt.encryptor.password=1234attached?
Thank you so much in advance!
Procfile can't use environment variables. Use a shell script to start the application instead of invoking java -jar directly in Procfile.
Procfile:
web: /bin/sh start_server.sh
start_server.sh
#!/bin/bash
JAVA_OPTS='-Djasypt.encryptor.password=1234'
exec java $JAVA_OPTS -jar myapp.jar
references: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/platforms-linux-extend.html

How to use docker passed environment variable in log4j2?

I have a spring-boot based application that uses log4j2.xml in a dockerized environment.
When I launch the docker I pass -e "LOG4J_PATH=/tmp/app.log" to specify where the logs should go to.
Next, in the log4j2.xml I use fileName="${env:LOG4J_PATH}" but this doesn't work. I searched the web for hours and thus tried double $ and tried sys instead of env... nothing.
This System.getenv("LOG4J_PATH") and (new EnvironmentLookup()).lookup("LOG4J_PATH") work fine, so I know that the variable is being passed to the running image ok, but from some reason the log4j doesn't seem to pick it up.
If I run this not via a docker and set the LOG4J_PATH environment variable in my .bash_profile it works fine so this is something between docker and log4j.
What am I doing wrong?
I believe you need to change the key value structure a bit for your passed environment variable. Can you try
docker run -e LOG4J_PATH='/tmp/app.log'

Starting Spring boot applications from script

Using normal spring mvn commands, I can start a spring boot application from command line and terminate it with Control+c. I however have created a bunch of services which I will dockerize later. For now they are plain java jar files generated by mvn. How do I use a python script or a Bash script to start them one by one and then use a script to terminate them. Is there some way where i start it and script won't block and the app will have a name that i can later use to stop the app?
I would follow the documentation to install Spring-Boot application as a Unix/Linux service.
All you have to do is to add this dependency to your pom.xml:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
After adding the plugin you should install and create a symlink to your application (exact part of documentation):
Assuming that you have a Spring Boot application installed in
/var/myapp, to install a Spring Boot application as an init.d service
simply create a symlink:
$ sudo ln -s /var/myapp/myapp.jar /etc/init.d/myapp
Once installed,
you can start and stop the service in the usual way. For example, on a
Debian based system:
$ service myapp start
Then you are able to create a bash script to start, stop or restart your applications in a clean way.
You could use a script to achieve this. For example a startup.sh may look like this. It will start the application and write the process id to /path/to/app/pid.file
#!/bin/bash
nohup java -jar /path/to/app/hello-world.jar > /path/to/log.txt 2>&1 &
echo $! > /path/to/app/pid.file
And a shutdown.sh may look like this.
#!/bin/bash
kill $(cat /path/to/app/pid.file)
You can find more detail in my post. https://springhow.com/start-stop-scripts-for-spring-boot-applications/
You can launch each jar with the following command (in a bash script):
java -jar service1.jar &
Then, you can kill each process with the following command (in a bash script):
pkill -f service1.jar
pkill will terminates all processes containing the provided name. Be careful that your keyword only identifies your process, so you don't terminate other processes by mistake.
This script make it easy, auto find newest version of jar file:
https://github.com/tyrion9/spring-boot-startup-script
./bootstrap.sh start
./bootstrap.sh stop
./bootstrap.sh restart

Access environment variable in .conf file for spring boot app

I have set environment variable by executing the command
export test=abcd
I can see test=abcd when I run printenvcommand
I have deployed a springboot.jar application and I am passing the JAVA_OPTS from the springboot.conf file.
JAVA_OPTS='-Dspring.profiles.active=aaa -Denv=$test'
I started the app by service springboot start . When I check the process, env variable doesn't have the value of $test environment variable.
/usr/bin/java -Dsun.misc.URLClassPath.disableJarChecking=true -Dspring.profiles.active=aaa -Denv=.
How can I access the environment variable in the conf file? I read somewhere the environment variables will be stripped off when run as service. Basically I want to run as service springboot start which internally executes the below command
java -Dspring.profiles.active=aws -Denv=${whatever is set for env environment variable} -jar springboot.jar
I have tried the below configurations but nothing worked
JAVA_OPTS='-Dspring.profiles.active=aaa -Denv='$test
JAVA_OPTS='-Dspring.profiles.active=aaa -Denv='${test}
JAVA_OPTS='-Dspring.profiles.active=aaa -Denv=${test}'
JAVA_OPTS="-Dspring.profiles.active=aaa -Denv=$test"
Be careful about your quotes. Assuming that you use a "normal" shell, variables won't be substituted in single quotes.
java -Dspring.profiles.active=aws -Denv="$myvariable" -jar springboot.jar should lead to env being available in the JVM, no matter if you run it as a service or not.
If you can't get it to work, try to specify a hard coded value like this java -Dspring.profiles.active=aws -Denv=foo -jar springboot.jar. If env is now available in the JVM, your problem is with your shell or run mechanism. Verify that the user who runs the command (i.e. do you use sudo?) has the variable set.
I had the same problem where my .conf was referencing an environment variable which was in the .bashrc.
What I found out is:
The problem is service strips all environment variables but TERM, PATH and LANG which is a good thing. If you are executing the script directly nothing removes the environment variables so everything works.
https://unix.stackexchange.com/questions/44370/how-to-make-unix-service-see-environment-variables
One solution would be to install your app as a systemd service:
https://docs.spring.io/spring-boot/docs/1.3.x-SNAPSHOT/reference/html/deployment-install.html
Or another way is to use docker and you can specify extra configuration in the docker file, like loading a file which contains your environment variables.
As those solutions where not available in my case I ended up with having the value in the .conf file, like: -Denv=prod

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