how to set location of jvm crash log files - java

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.

Related

How to set custom environment variables in tomcat?

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

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() call in JVM

I am setting environment variable in my machine using export MY_KEY=foo. And I am trying to fetch it in JVM using System.getenv("MY_KEY"). This returns null. But running echo $MY_KEY shows foo on the terminal.
I have tried restarting the IDE. Doesn't work, still.
The environment variable is only available to sub processes of the shell that exported it. Did you start your IDE from that shell?
If you want the variable to be available all the time, you need to add it
to the /etc/profile file or create a extra file in /etc/profile.d. It depends on your operating system.

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.

How to specify a unique name for the JVM crash log files?

When the JVM crashes it generates a log file that is saved (by default) in the current folder of the application and has a name respecting the following format: hs_err_pid[PID].log
I need to make the JVM save this file in a different folder with a desired name. So, I use this command line argument for the virtual machine:
-XX:ErrorFile=./log/jvm_error_pid%p.log
It is working, but I don't like something about this solution. Let's assume the log folder already contains a file named jvm_error_pid5000.log. If there is a future crash on a JVM that has 5000 PID, then JVM does not override the jvm_error_pid5000.log file from the log folder and it saves this log file in a totally different place (from what I tested in the TEMP folder of the current OS user). It doesn't even rename the new file by appending a random string to assure uniqueness.
I haven't found anything regarding this uniqueness problem on the Oracle documentation page about crash log files. I would like to know if there is a way to improve that command line argument so that it will always generate different crash log file names. For example, I want to use the command line argument to put the date and hour in the file name:
-XX:ErrorFile=./log/jvm_error_pid%p_%d_%h.log
JVM does not expand placeholders in ErrorFile other than %p. But you may modify your shell script that launches Java, and use shell variables instead.
#!/bin/bash
TS=`date +%F-%H%M%S`
java -XX:ErrorFile=/tmp/hserr_%p_$TS.log ...
one thing you can do is just email the error log to some email address
java -XX:OnError="cat hs_err_pid%p.log|mail support#acme.com" \ MyApplication
Refer http://www.oracle.com/technetwork/java/javase/clopts-139448.html#gbmum for more information.

Categories