How to set custom environment variables in tomcat? - java

I have few key- value pair variables in my program which is hard coded now.
String pswd = StringUtils.defaultString(System.getProperty("KEY_STORE_PASSWORD"), "password");
String algorithm = StringUtils.defaultString(System.getProperty("KEY_STORE_ALGORITHM"), "SunX509");
I need to load those values dynamically. For that purpose, I need to set those values as environment variables(custom) in Tomcat. I am running the application using the Tomcat plugin. I tried with setenv.bat file concept. I added the following line into it.
set KEY_STORE_PASSWORD=password
but it I am not getting it my logs. I used another method
set JAVA_OPTS=-DKEY_STORE_PASSWORD=password
I added this line, tried, yet nothing...except null get printed in the console. I don't know what is JAVA_OPTS, I didn't add any System environment variables for Tomcat. Should I add them first?? What are those variables we need to add as environment variables for Tomcat?? Is JAVA_OPTS one of them??
Can I create custom environment variables without creating them??
String pswd1=System.getProperty("KEY_STORE_PASSWORD");
logger.info("pswd1 from tomcat"+ pswd1);
These are the printing statements I am using.

This was definitely a rough one, because all of the approved answers here in the stack over flow failed in my case. I tried with both Setenv.bat & Catalina.bat files I even tried creating a configuration file in the CATALINA_HOME/conf folder of the tomcat, called variables.conf declaring all the variables, both key and values,I need to access as an environment variable.
Pass user defined environment variable to tomcat
All of these methods in the above link failed and finally I tried this one using JVM Settings of the Tomcat
Open Window -->> Preferences -->> Tomcat -->> JVM Settings
Here in the Append to JVM Parameters, add your variables which you need to work as environment variables(which can be accessed in the entire project using System.getProperty() ).
An example is shown in the picture below:
Here my variables are :
KEY_STORE_PASSWORD=
KEY_STORE_ALGORITHM=
KEY_STORE=
KEY_STORE_PROTOCOL=
which can be written to JVM Settings as -D followed by variable [equals to] variable value.
Eg: -DKEY_STORE_PASSWORD=password
If you have any queries, please do ask.

#Bruce Wayne
Thanks for this answer! I could not find an example of how to do this anywhere!
ADDITIONAL HELPFUL INFO for debugging with VSCode and the Tomcat for Java Extension
When debugging with Tomcat by right clicking on the tools folder and selecting Debug with Tomcat Server launch.json is NOT used. So trying to set the environment variables there does not work.
Right click on the Tomcat server and select "Customize JVM Options"
Then set your variables as indicated above with the -D option in the jvm.options file that appears and save
so
-DVARIABLENAME=VALUE

Related

difference between environment variables and System properties

iam using the below link to understand environment variables and system properties.
https://docs.oracle.com/javase/tutorial/essential/environment/env.html
The link says environment variables are set by OS and passed to applications.
When i fetch environment variables using System.getenv() it shows me lot of properties which i never set.
So it must be OS (im using macOS) which had set these properties.
Some of the properties in System.getenv() are MAVEN_CMD_LINE_ARGS, JAVA_MAIN_CLASS_1420, JAVA_MAIN_CLASS_1430.
My question is why would OS would like to set the java specific properties in environment variables? Ideally these should be set by JVM (in System.properties()).
P.S.: From whatever i have read on net i understand that environment variables are set by OS and System.properties() are set by JVM
Also if someone can point me to a good link on environment variable and System.properties it will be very helpful. Iam very confused between the two.
Environment variables is an OS concept, and are passed by the program that starts your Java program.
That is usually the OS, e.g. double-click in an explorer window or running command in a command prompt, so you get the OS-managed list of environment variables.
If another program starts your Java program1, e.g. an IDE (Eclipse, IntelliJ, NetBeans, ...) or a build tool (Maven, Groovy, ...), it can modify the list of environment variables, usually by adding more. E.g. the environment variable named MAVEN_CMD_LINE_ARGS would tend to indicate that you might be running your program with Maven.
In a running Java program, the list of environment variables cannot be modified.
System properties is a Java concept. The JVM will automatically assign a lot of
system properties on startup.
You can add/override the values on startup by using the -D command-line argument.
In a running Java program, the list of system properties can be modified by the program itself, though that is generally a bad idea.
1) For reference, if a Java program wants to start another Java program, it will generally use a ProcessBuilder to set that up. The environment variables of the new Java process will by default be the same as the current Java program, but can be modified for the new Java program by calling the environment() method of the builder.

System.getenv still picks up deleted env variable value on MacOS Mojave - Java

I added some exportable environment variables in my bash_profile and my profile files in the following format export "X=y". This worked as it should, now I want to remove them permanently . I've tried the following methods:
Deleting the exported variables from the bash_profile and the profile files, and saving the files, and calling source ~/.bash_profile and source ~/.profile.
Called "unset X" in terminal window. Before I could call "echo $X" which would display y, now it displays nothing.
Rebooting the Mac Computer.
Still however, whenever I call Java's System.getenv(X), env variable X's value (y) is still returned. What else do I need to do to completely eliminate an env variable from my system in MacOS Mojave?
It appears you believe environment variables are global. That is, modifying the value in one program, such as a running terminal, will affect the value in a different program. That is not how env vars work in a UNIX like OS. Each process is provided a copy of the env vars provided by the parent process. That is, they are inherited from the parent process.
The fact that you have to unset X in a terminal to remove it means that either it is being inherited by the shell from the terminal process or your shell is setting it. In the latter case the specific files read when a shell starts depends on the shell. But /etc/profile is read by most interactive shells so you might want to look there.
You say your Java app is run by Tomcat but failed to mention how Tomcat is started. That is important for the reasons I mention above.
Note that macOS uses a daemon named launchd to manage running most services. Those services are configured via "plist" files. See man launchd.plist. Those launchd config files support defining custom env vars. That is slightly unusual but worth looking at. See if any of the files in ~/Library/LaunchAgents, /Library/LaunchAgents, or /Library/LaunchDaemons mention the env var.

Java environment variables under Windows 2012R2

We are trying to run Apache-Tomcat which would start / stop as a service. However, when trying to set it up, we get error messages as for unset variables, making it impossible to set it as a service. Looking at the file, and given that this is a .BAT file, as provided by the distribution, is there an easy way to set the JAVA-HOME and other required variables for Java to be set globally for the box ? Our main challenge is to get Apache-Tomcat copied / setup through a script, and the environment variables globally (and permanently) set so that when the server is rebooted, or the service started/stopped/restarted.
The JAVA_HOME environment variable is only used when running the service.bat file. Once the service has been created, it has embedded the value, so changing a global JAVA_HOME environment variable will make no difference.
When you want to use a different JAVA_HOME value, you have to deregister the service and reregister with the new value.
This is regardless of Windows version. Also remember to run service.bat "as admin".
There is a good reason why a registered Tomcat instance is not using global environment values. As an example, we're running 6 different Tomcat instances on our UAT server, each with a different combination of Tomcat version and Java version. We couldn't do that if all the instances were using a single global JAVA_HOME or CATALINA_HOME value.

Pass VM Argument to Apache Tomcat [duplicate]

This question already has answers here:
How to pass the -D additional parameter while starting tomcat?
(6 answers)
Closed 5 years ago.
I have a webProject with a VM Argument called "-Dfolder"
I use that argument on applicationContext like this:
<value>file:${FNET_CORE_CONFIG}/conf/${folder}/jdbc.properties</value>
In Eclipse, for testing, i use "Run Configuration" to set the value like this:
-Dfolder=Dev
Now, I want to test my webapp on Apache Tomcat so I need to set/send the folder VM Argument.
How I do that?
I have to use setenv.sh? How?. Can someone give me and example?
Thanks and sorry for my english
I don't know what version of Tomcat you using, but in Tomcat 7 in file catalina.sh you can specify variable CATALINA_OPTS and this variable will pass to jvm.
But maybe setting environment variable isn't a best way to achive your goal. Maybe best will be creation of separate "app.properties" file, and including it in applicationContext like this:
<context:property-placeholder location="classpath*:app.properties" />
And solution for catalina.sh
# CATALINA_OPTS (Optional) Java runtime options used when the "start",
# "run" or "debug" command is executed.
# Include here and not in JAVA_OPTS all options, that should
# only be used by Tomcat itself, not by the stop process,
# the version command etc.
# Examples are heap size, GC logging, JMX ports etc.
example:
CATALINA_OPTS="-Dfolder=Dev"
EDIT:
for windows it should be something like set CATALINA_OPTS="-Dfolder=Dev"
EDIT:
In Spring configuration you can use system property just like ${propertyname}, and also can include file with property definition, with context:property-placeholder, and all defined in that file properties also become avaliable in config.
For example, you have base set properties: config.properties, and set of files with db connection settings (DEV.properties, UAT.properties, PROD.properties). So, how can you include different properties for different environment? It can be done it many ways, for example, set system properties in catalina.bat
set CATALINA_OPTS="-Dbuild=DEV"
and in applicationConfig.xml
<context:property-placeholder location="classpath*:${build}.properties, classpath*:config.properties" />
Or you can create different build configuration and include in final WAR only one properties (DEV, UAT, PROD) for each build configuration. In applicationConfig set something like:
<context:property-placeholder location="classpath*:*.properties" />
Go to $CATALINA_HOME and edit setenv.sh file by adding the parameters with the value.
If you want to mass multiple parameters, separate them using space
E.g.
cd /opt/tomcat/bin/
sudo nano setenv.sh
edit the line
CATALINA_OPTS="${CATALINA_OPTS}"
to
CATALINA_OPTS="${CATALINA_OPTS} -Dparam=value -Dparam2=value2"
restart tomcat:
service tomcat restart
you should now be able to see the arguments passed to tomcat when you run:
ps aux | grep tomcat
Made it work in Windows, by generating a setenv.bat file in the same directory as catalina.bat and startup.bat (as recommended in catalina.bat)
and put in the contents of the .bat:
set CATALINA_OPTS="-DyourVariableName=yourValue"
That's all. I liked this way as it looks pretty clean

how to set location of jvm crash log files

I need to configure where the jvm crash logs are created. I like the name they have (hs_err_pid.log) but I want them created in an specific folder.
In here you can see that you can use the
-XX:ErrorFile=./hs_err_pid<pid>.log
param to set the FILE created, but if you set this to a folder, so the file is created in that folder with the original naming convention, it does not work, it is ignored.
I have been testing this by crashing jvm 1.6 from this questions, using this:
PathDasher dasher = new PathDasher(null) ;
Anybody knows a way to achieve this?
-XX:ErrorFile=/var/log/java/hs_err_pid%p.log works.
See http://www.oracle.com/technetwork/java/javase/felog-138657.html
The parameter does not allow for environment variables, but you can use environment variables in a launcher script (e.g. .sh or .bat) and the OS will do the substitution. However, this will use the value of the environment variable at the time of starting the JVM and not when the file is written later. Furthermore, environment variables do not work when setting Run properties in Eclipse.
The JVM will not create intermediate directories saving the crash dump. The crash dump will be saved at the default location if the specified folder does not exist.
You have to use this as
java -XX:ErrorFile=/var/log/java/hs_err_pid%p.log -Xbootclasspath/p:. Crash
in command prompt.
Here, Crash is my java file.

Categories