Get Unix Thread Dump - java

I am trying to get a unix (solaris and linux) thread dump on a java application.
1) When the java application is a tomcat web application,
using kill -3 , the dump goes to the catalina.out file, as this is standard output.
kill -3 pid > td.out does not work.
2) For another spring standalone java application, how do I find the standard output for it.
I have used:
kill -3 pid, and I have checked in my application logs, and I cannot find anything.
Please advise how I can determine standard output for the java application and see the thread dump.
Thanks,
B.

If you're using OpenJDK or Sun JDK 6 or later, try the jstack command in the bin folder. This is useful when redirecting standard out to a file is problematic for some reason. Execute the following, passing in the Java process ID:
jstack -l JAVA_PID > jstack.out

Try using Process
Process p = null;
String cmd[] = {"bash","-c","ps -C java | awk '{ print $1; }' | sed -n '2{p;q;}'"};
try
{
p = Runtime.getRuntime().exec(cmd);
try
{
p.waitFor();
System.out.println("Executed Successfully");
}catch(Exception e)
{
e.printStackTrace();
}
}catch(Exception e)
{
e.printStackTrace();
}
Then read the line by BufferReader and use the above function to kill and output the same
Explanation for the command :
ps -C java | awk '{ print $1; }' | sed -n '2{p;q;}'
" ps -C ProcessName " tells the process if its running with pid, here Java is used as ProcessName
" awk '{ print $1; }' " outputs the 1st row of the output
" sed -n '2{p;q;} " to display the 2nd column

Related

Grep for the 5 lines after a specific text string found in files

I have many java files, and I want to find how many times we are logging via
logger.isDebugEnabled(){
logger.Debug("some debug message");
}
To get an idea of how often we may be overusing the isDebugEnabled function. I have found the number of times we have called/where it is called via
grep -r "isDebugEnabled" --include=*.java . | wc -l
But I want to know how many of those are 1 line statements. Does anyone have a good script to search for this or any ideas on the most efficient way of doing this?
Don’t use grep for this, use the following AWK program:
prev ~ /isDebugEnabled/ && $0 ~ /logger\.Debug\("[^"]"\)/ {
print FILENAME ":" NR ": " $0
}
{
prev = $0
}
This program remembers the previous line in the prev variable and thereby allows you to compare two lines at a time.
To actually use it, write:
find . -name '*.java' -print \
| xargs awk 'prev ~ /isDebugEnabled/ && /logger\.Debug\("[^"]"\)/ { print FILENAME ":" NR ": " $0 } { prev = $0 }'
As mentioned in comments grep provides options to print certain number of lines after and before match.
To print lines after match:
grep -A 2 "string to match" file.txt
To print lines before match:
grep -B 2 "string to match" file.txt
Before you try to write a script giving one final answer, try different approaches for insight what is best for what you want. Test with one file.
Do you think, that logger.Debug("The database has ", getDbNum(), "and the server has ", getRemoteNumSpecial(), "records."); is a simple oneliner?
You can collect some numbers for a first orientation. The examples beneath is using x.java as example sourcefile.
# Nr of isDebugEnabled calls
grep -c "logger.isDebugEnabled" x.java
# Some may be comment with //
grep -c "//.*logger.isDebugEnabled" x.java
# How much debug-lines
grep -c "logger.Debug" x.java
# How much debug-lines with more than 1 parameter (having a ,)
grep -c "logger.Debug.*," x.java
# How much debug-lines without the closing ) on the same line
grep "logger.Debug" x.java | grep -v "Debug.*)"
# How much logger.isDebugEnabled() without a logger.Debug on the next line
grep -A1 "logger.isDebugEnabled" x.java | grep -c "logger.Debug"
# How much logger.Debug a "}" on the next line
# The debugline might have a }, so skip lines with logger.Debug
grep -A1 "logger.Debug" x.java | grep -v "logger.Debug" | grep -c "}"

java processbuilder ffmpeg pipe

i try to run ffmpeg out java. here my code:
String[] temp = {"ffmpeg\\ffmpeg.exe","-i","input_track.ac3","-threads","0","-af","volume=volume="0.0"dB","-acodec","pcm_s32le","-ac","6","-ar","48000","-f","wav","-","|","ffmpeg\\fdkaac","--ignorelength","-m","1","-o","ouput_track.aac","-"};
ProcessBuilder pb = new ProcessBuilder(temp);
Process p = pb.start();
int ev = 0;
if (p.waitFor() != 0)
{
ev = p.exitValue();
}
i try the comand at windows cmd, here have a problem with "|" at the ffmpeg command line.
maybe someone say my fould?
best regards
This question is similar to How to make pipes work with Runtime.exec()? ... except that it is for Windows.
The problem is essentially the same: the exec methods don't understand shell syntax such as pipes, input or output direction and so on. The solution is essentially the same too: exec the appropriate shell and get that to handle the shell syntax.
In this case, try something like this:
String[] temp = new String[] {
"cmd", "/c",
"ffmpeg\\ffmpeg.exe -i input_track.ac3 -threads 0 " +
"-af volume=volume=\"0.0\"dB -acodec pcm_s32le -ac 6 " +
"-ar 48000 -f wav - | " +
"ffmpeg\\fdkaac --ignorelength -m 1 -o ouput_track.aac -"
};
Note that the actual command is a single string. (The quotes around the 0.0 look a bit strange, but that is what you have in your question.)
| is a shell pipe character, in java you'll have to either run this command in a shall (bash -c "the whole commandline | goes here"), or you'll have to run two processes (the one before the | and the one after), where the stdout of the first writes into the stdin of the second. For this, you'd typically use redirectOutput(Redirect.PIPE) and redirectInput(Redirect.PIPE).

shell script if statement executed from java?

I'm trying to execute unix commands thru a java program. Some of these commands involve an if-then-fi statement. Can this be done thru java / Runtime class? Seems like it only handles 1 command at a time.
I'm looking to do something like this:
grep 'Error One' SystemErr.log > $HOME/tempFiles/output.txt
grep 'Error Two' SystemErr.log >> $HOME/tempFiles/output.txt
grep 'Error Three' SystemErr.log >> $HOME/tempFiles/output.txt
.
.
if [ -s $HOME/tempFiles/output.txt ]
then
mail -s "Subject here" "a#b.com" < $HOME/tempFiles/output.txt
fi
Basically, I just want to email the file (results) if the grep found anything.
I want to use java instead of a direct shell script so that the errors I search for can be database-driven, easier to change.
I know I could read the file myself in java and search/parse it myself. But grep and other unix commands have a lot of built-in functionality I want to use to make it easier.
Any ideas, or am I totally on the wrong track?
Here is some code, using simpler commands, but basically equivalent:
public static void main( String[] args ) throws Exception {
try {
ProcessBuilder pb = new ProcessBuilder( "/bin/bash", "-c",
"echo one >/tmp/xxx && echo two >>/tmp/xxx && " +
"if [ -s /tmp/xxx ]; then cp /tmp/xxx /tmp/yyy; fi" );
File log = new File( "/tmp/log.txt" );
pb.redirectOutput(ProcessBuilder.Redirect.appendTo(log));
Process process = pb.start();
process.waitFor();
} catch( Exception e ){
// ...
} catch( Error e ){
// ...
}
}
The trick is to put it all into a single shell command so that you can call /bin/bash with the -c command option.
If composing this command is too complicated, write a shell file and source that.

How can i tell Java code run the script as it was running from command line as normal user?

When i run this script manually then Browser chrome open the site in one tab (which is PERFECT exactly how i needed)
But when i run the same script using Java sample code 10 times, it open Browser but 10 times same page 10 TABs.
Q. How can i tell Java code please run it as it was suppose to be running manual execution (so that i have 1 TAB only?) ?
BASH: /var/tmp/runme.sh
(ran 1o times and still have always 1 tab as expected)
export DISPLAY=:0.0
ps aux | grep chromium-browser | awk '{ print $2 }' | xargs kill -9;
sleep 8;
chromium-browser --process-per-site --no-discard-tabs --ash-disable-tab-scrubbing -disable-translate "http://www.oracle.com" &
Java: launch 10 times that script
system("/var/tmp/runme.sh &");
public static String system(String cmds) {
String value = "";
try {
String cmd[] = { "/bin/sh", "-c", cmds};
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = reader.readLine();
while (line != null) {
value += line + "\n\r";
line = reader.readLine();
}
}
catch (IOException ioe) {
ioe.printStackTrace();
}
catch (InterruptedException ie) {
ie.printStackTrace();
}
return value;
}
Java is weired sometimes. Its solved.
1( kill chromium browser before killing the java
2( after killing chromium browser then launch the java application
3( now the tab is 1 and browser is 1
BEFORE: (wrong)
export DISPLAY=:0.0
pkill java;
java -cp SystemV.jar Main.Start "boot chromium now with 1 tab and 1 browser" &
ps aux | grep chromium-browser | awk '{ print $2 }' | xargs kill -9;
chromium-browser --process-per-site --no-discard-tabs --ash-disable-tab-scrubbing -disable-translate "http://www.oracle.com" &
AFTER:
export DISPLAY=:0.0
ps aux | grep chromium-browser | awk '{ print $2 }' | xargs kill -9;
chromium-browser --process-per-site --no-discard-tabs --ash-disable-tab-scrubbing -disable-translate "http://www.oracle.com" &
pkill java;
java -cp SystemV.jar Main.Start "boot chromium now with 1 tab and 1 browser" &
echo "it works now"
Fist remove & from this line system("/var/tmp/runme.sh &");
Second, maybe since, you are using this: "/bin/sh", Java is running the script as different shell every time you invoke using Runtime?
and you are executing /var/tmp/runme.sh from the same shell everytime.
Note: /bin/sh is an interpreter and with Java Runtime you are invoking multiple instances of it to execute your script every time.

Piped unix command not executing in java Program

I am trying to get the memory usage for a particular Process using its pid in a java program
using the following command
ps -eo pid,pmem,comm | grep java | awk '{print ($2)}'
While this command works on unix terminal, it does not work in java I keep on getting null result even when I run another java program (to populate the ps table with java processes).
String[] PipedCommand = {
"/bin/bash",
"-c",
"ps -eo pid,pmem,comm | grep java | awk '{print ($2)}'"
};
Process command1=Runtime.getRuntime().exec(PipedCommand);
command1.waitFor();
BufferedReader reader1=new BufferedReader(new InputStreamReader(command.getInputStream()));
String line1=reader1.readLine();
if(line1 != null)
{
System.out.println(" Memory percentage is "+line1);
}
I would appreciate if someone could tell me if there is something wrong with the approach

Categories