Access environment variable in .conf file for spring boot app - java

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

Related

Environment variables are not getting expanded in JAVA_TOOL_OPTIONS

I am trying to integrate a javaagent for application monitoring. I'm using docker and I've setup an OpenJDK base image which is inherited by other application images.
Since javaagent requires a path to the jar file, for maintenance purposes I've defined the path in the base image as another env variable(AGENT_PATH) and I want to reuse the same env variable across all my app images. For some reason the environment variable isn't picked and the application container exits with error.
Base Image's Dockerfile
AGENT_PATH=/agent/agent.jar
This is how I've configured JAVA_TOOL_OPTIONS in application's Dockerfile.
JAVA_TOOL_OPTIONS="-javaagent:$AGENT_PATH + other JVM options"
This is the error message
Picked up JAVA_TOOL_OPTIONS: -javaagent:$AGENT_PATH
Error opening zip file or JAR manifest missing : $AGENT_PATH
Error occurred during initialization of VM
agent library failed to init: instrument
Why is AGENT_PATH not getting substituted properly ?
I've grepped through Hotspot implementation for understanding. I've found this.
This will depend on the Docker step. If you use RUN step the variables processing is not supported:
Unlike the shell form, the exec form does not invoke a command shell. This means that normal shell processing does not happen. For example, RUN [ "echo", "$HOME" ] will not do variable substitution on $HOME. If you want shell processing then either use the shell form or execute a shell directly, for example: RUN [ "sh", "-c", "echo $HOME" ]. When using the exec form and executing a shell directly, as in the case for the shell form, it is the shell that is doing the environment variable expansion, not docker.
In dockerfiles, all directives require a certain codeword. Assigning an environment variable is no different from this and needs the ENV codeword (read here).
Using this, the excerpt of your dockerfile should read
ENV AGENT_PATH=/agent/agent.jar
I was facing the same issue where the environment variables set in the JAVA_TOOL_OPTIONS were not getting substituted. So I had to mention those variables as -D parameters along with java command.
java -Djavax.net.ssl.keyStorePassword=$KeyStore_Secret .....
You can check if that is the case by hardcoding the values in the JAVA_TOOL_OPTIONS and it should work. Meanwhile, I am still looking at the reason for this.

How to pass properties to Java when using COMPSs

I have a java application which is launched with a settings file passed as a property as follows:
java -DpropertiesFile=/path/to/properties/settings.properties -jar /path/to/jar/file.jar
I would like to know how/if I can pass this properties file when running my application with COMPSs framework.
Thanks
Currently the only option is to set the environment variable _JAVA_OPTIONS. This is variable is read once the JVM is started.
In your example it would be:
export _JAVA_OPTIONS=-DpropertiesFile=/path/to/properties/settings.properties
NB: I used export as an example, use whatever command your system has to set environment variables.

System.getenv() does not list all the environment variables

I have noticed that some of my environment variables are not being picked up by the JVM.
In my .bash_profile I defined the following:
IO_HOME='some_value'
export IO_HOME
and by doing in shell:
echo $IO_HOME
I get the correct result.
But neither System.getProperties() nor System.getenv() is showing this variable being set. I tried both Java 6 and Java 7.
Is there something I am missing?
Exporting environment to spawned processes is pretty stable; if System.getenv() is not including a variable then it is because it is not in the environment. A couple of things to check, both relating to how the process is started:
Are you starting the java process from an environment where the variable is exported? For example, if it is in your .bash_profile and you are executing the java program from a menu or desktop then you have to log out and log in after adding it in .bash_profile for your desktop to see the variable.
Is the variable explicitly removed from environment for the process? ProcessBuilder allows this, as do most of all APIs that spawn processes.
One thing to try is to start the process from command line shell, after ensuring the variable is exported in that shell.
From Windows, I recently saw some crazy behaviour where IntelliJ refused to show all env vars from System.getenv() after setting either user or system env vars. The trick was to launch IntelliJ from a DOS box. For Windows users: Maybe a reboot (or logoff/logon) will fix the issue.

Java System.getEnv()

In mac OSX and in Linux CentOS, I insert a new system environment variable (i.e. "MYAPP") using .bashrc & .bash_profile. I even restarted my laptop (mac) and my server (linux).
When I use the command line "env", that environment variable showed with the correct value. But somehow every time I try to get it in a Java app (desktop app or web app or EJB or servlet any other java app) in either mac or linux, that environment variable ("MYAPP") is not retrieved.
I tried to iterate through the entire environment variables that Java can retrieve and it turns out that it retrieves every environment variables other than "MYAPP". This is very odd.
Anyone know how to solve this?
Did you export MYAPP=...? Exporting the variable makes it available to child processes, like java being run by your shell.
In Linux, if you only set the variable (or export it) in a bash session, it will be available to a kind of "sub" session, which is only available to the command you just executed, and nothing else.
You could probably use the dot operator in bash (also called "source" command). From the page:
When a script is run using `source' it runs within the existing shell, any variables created or modified by the script will remain available after the script completes.
So you could try doing . export VARIABLE=value, and then running your java program. This is similar to setting a variable in a Windows terminal, and then opening a new terminal and expecting the env var to be there. It won't.
This way, you are telling bash "this command should be available in this specific session (the session's process)". OTherwise you are telling it "set this env var for the bash session that will end after I run this export command" thus, it won't exist when you run your Java program.
After having defined and exported the environment variable. Launch your IDE from the same Terminal.
Try to write
"$System.env.STOREPWD"

Setting Environment Variable from Eclipse vs. System

I am using the Gurobi Optimizer, for which I need to set two environment variables: LD_LIBRARY_PATH and GRB_LICENSE_FILE.
If I set the variables using Eclipse (Run As --> Run Configuration --> Environment), everything works correctly. If I set the variables through the system (using export in Linux), I get the error
no GurobiJni46 in java.library.path
Any ideas why this happens and how to fix this?
In the end, I want to run a web application in Tomcat, which would require those variables set correctly.
In the case where you have set the environment variable using export are you then running your application from inside Eclipse or are you running your application from the command line?
The launcher for Eclipse usually explicitly sets the path using the command line switch -Djava.library.path which would overwrite what you have set in the environment.
If you set the LD_LIBRARY_PATH before running Tomcat it would work, provided that Tomcat doesn't override it in one of its start-up scripts!

Categories

Resources