Trying to collect thread dump of Apache Tomcat8.5 in windows server I ended using jstack with psexec as follows(as using jstack directly wasn't possible, so I'm using pexec to execute jstack using syetm process):
PsExec.exe -s "C:\Program Files\Java\jdk1.7.0_40\bin\jstack.exe" -l 5340 > dumps.txt
with 5340 is the PID of the running Tomcat8 process.
The execution started without any errors and it shows this output:
PsExec.exe -s "C:\Program Files\Java\jdk1.7.0_40\bin\jstack.exe" -l 5340 > dumps.txt
PsExec v2.2 - Execute processes remotely Copyright (C) 2001-2016 Mark Russinovich Sysinternals - www.sysinternals.com
Starting C:\Program Files\Java\jdk1.7.0_40\bin\jstack.exe on VMNAME...
When I check th dumps.txt I find it empty, even I'm running The command line as Admin.
Thnks for your help!
As a conclusion to the discussion. You need to use the same VM version for executing a jstack command as the VM version you are going to inspect. In case of any errors, you could try a -F param to jstack.
Also, you don't need PsExec tools on newer VMs anymore.
Related
Mac 10.10.5 here, using docker-machine to create a VirtualBox host VM for my local Docker. I have a project that builds an executable JVM located at build/libs/myapp-SNAPSHOT.jar. My Dockerfile, which is located in the root of the project, looks like:
FROM frolvlad/alpine-oraclejdk8:slim
VOLUME /tmp
ADD build/libs/myapp-SNAPSHOT.jar myapp.jar
RUN sh -c 'touch /myapp.jar'
ENTRYPOINT ["java","-jar","/myapp.jar"]
Please note, I don't wish to push my images to any registry, just keep/run them locally (for now). When I run:
docker build -t myorg/myapp .
I get the following console output:
myuser#mymachine:~/sandbox/myapp$docker build -t myorg/myapp .
Sending build context to Docker daemon 42.69 MB
Step 1 : FROM frolvlad/alpine-oraclejdk8:slim
slim: Pulling from frolvlad/alpine-oraclejdk8
d0ca440e8637: Downloading [=================================================> ] 2.295 MB/2.32 MB
0f86278f6be1: Downloading [=================================================> ] 3.149 MB/3.172 MB
c704a6161dca: Download complete
And then the command-line just hangs after printing that "Download complete" message. I've waited for as long as 30 minutes (!!!) and nothing happens.
Any ideas where I'm going awry?
The VM is probably hanging. Try the following: https://github.com/docker/machine/issues/1819#issuecomment-138981139
docker-machine rm -f default
rm -fv ~/.docker/machine
docker-machine -D create -d virtualbox default
There are more issues about this on OSX.
I think the best practice is to setup a Linux native build box if you are doing any serious development. That way you can run docker without any VM overhead(which is ironically one of the major pain points docker is trying to solve)
There's also a Docker Beta program which runs on libcontainer natively on OSX and Windows.
At first let me describe my issue.
I configured Jenkins and after build action I called shell script to run bash script on remote server.
The shell script starts application via command
java -Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=xxx
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-XX:+HeapDumpOnOutOfMemoryError -jar name.jar "BUILD_PARAMETER"
I see logs from my application in Jenkins build, and it's keep build process running. I need to finish it after running
sh run command. Is it possible?
If you're doing this using Jenkins you will need to use the nohup notation as in the comments as well as specifying a non-numerial PID for the process. Jenkins tries to clean up after a job finishes by killing any processes it starts.
BUILD_ID=dontKillMe nohup <-your command -> &
the above command should work
https://wiki.jenkins-ci.org/display/JENKINS/Spawning+processes+from+build
Your shell script need to fork a process, and return, otherwise Jenkins thinks your shell script is still running (which it is, if it's not forking the process and returning).
You have not provided the command you use to launch your application, but a common way to fork a process in linux is:
nohup <your command here> &
I have a start function, and I put it in a script resides on a remote site, the function's code shows below.
function start() {
cd $install_dir
mkdir -p logs
export classpath=$classpath:$target_jar
nohup java -Xms2048m -Xmx8192m -server -XX:PermSize=128m -XX:MaxPermSize=256m \
-XX:+PrintGCDetails -XX:+PrintGCDateStamps \
-XX:-OmitStackTraceInFastThrow \
-cp $target_jar $main_class >> logs/jvm.log 2>&1 &
echo "Service started, see logs"
}
And when I try to call that function use ssh ssh xxx#host "./service.sh start", I can not start the java process, I only got the response message "Service started, see logs" and there's no error, the jvm.log is also empty. It apparently to me that my script has executed, but the target java process didn't run.
If I logon to that remote site, and execute ./service.sh start, it works.
Since you were able to run the service manually, the ssh and script part is fine.
What could go wrong is the environment. For example you referred java without absolute path. Hence your may be running a different version of it. It is also possible that variable for shared library loading (LD_LIBRARY_PATH) are having different values.
Finally check for file permissins
I have the following simple script (test.sh):
#!/bin/bash
tail -f /var/log/dmesg > /tmp/output.log &
echo "THE END"
exit 0
After calling this test.sh script from a java program (remotely under ssh), the java console (eclipse) stay locked. Then,
1) If I manually kill the "tail -f /var/log/dmesg > /tmp/output.log" process in the server, the console unlocks and I get the "THE END" message in the console.
2) If I remove the "tail -f /var/log/dmesg > /tmp/output.log" from the script and run the java app, no lock happens and I get the "THE END" message in the console.
Is there anyone to run tail -f in bg through test.sh, and continue with the java app flow?
Try with nohup:
nohup tail -f /var/log/dmesg > /tmp/output.log &
SSH will sometimes wait for all processes to close the tty before exiting. nohup will set stdin to /dev/null and stdout/stderr to a file, so SSH can exit immediately (flushing any buffers that may be keeping "THE END" from showing).
There may also be some pitfalls on the Java side when it comes to running Unix system commands via Java. For example, if the standard I/O streams (stdout, stderr, stdin) of Unix-based operating systems are not being read in Java Threads, Unix system calls may unexpectedly block or even deadlock (for more detailed information on this topic please see Java exec - execute system processes with Java ProcessBuilder and Process (part 3) (2012).
Try the following Java sample code based on ThreadedStreamHandler.java, SystemCommandExecutor.java and ProcessBuilderExample.java that runs commands.add("ssh localhost /tmp/test.sh"); (it worked for me using the latest Eclipse Java EE IDE for Web Developers - Mac OS X version):
# References:
#
# - "Java exec - execute system processes with Java ProcessBuilder and Process (part 3)" (2012),
# http://alvinalexander.com/java/java-exec-processbuilder-process-3
#
# - "Running system commands in Java applications" (2012),
# http://alvinalexander.com/java/edu/pj/pj010016
#
# - "When Runtime.exec() won't: Navigate yourself around pitfalls related to the Runtime.exec() method" (2000),
# http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
mkdir -vp /tmp/com/devdaily/system
cd /tmp/com/devdaily/system
curl -LO http://alvinalexander.com/java/edu/java-exec/ProcessBuilderExample.java
curl -LO http://alvinalexander.com/java/edu/java-exec/SystemCommandExecutor.java
curl -LO http://alvinalexander.com/java/edu/java-exec/ThreadedStreamHandler.java
cd ../../..
# create commands.add("ssh localhost /tmp/test.sh");
printf '%s\n' 'H' ',s|ls -l.*tmp|ssh localhost /tmp/test.sh|' 'wq' |
ed -s com/devdaily/system/ProcessBuilderExample.java
echo '
#!/bin/bash
tail -f /private/var/log/system.log > /tmp/output.log &
echo "THE END"
exit 0
' > /tmp/test.sh
chmod +x /tmp/test.sh
javac com/devdaily/system/ProcessBuilderExample.java
java com/devdaily/system/ProcessBuilderExample
java -version
# java version "1.6.0_31"
# Java(TM) SE Runtime Environment (build 1.6.0_31-b04-415-10M3646)
# Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01-415, mixed mode)
# Eclipse Java EE IDE for Web Developers (Mac OS X version).
# Version: Juno Service Release 2
# Build id: 20130225-0426
#
# use the following menu sequences:
# Window --> Show View --> Console
# Run --> External Tools --> External Tools Configuration... --> Program (double-click) --> New_configuration
# Location: /usr/bin/java
# Working Directory: /tmp
# Arguments: com/devdaily/system/ProcessBuilderExample
Have a look at htis article, it describes main mistakes while working with processes. What you have to do is to add a Steam Gobbler - consumer of input streams, so that outer progrem not to stuck while writing to output, becouse of full buffer.
I am running Ubuntu server edition and I wanted to take a thread dump of Tomcat.
So, I first tried to find out which PID tomcat uses:
$ jps -l
5809 sun.tools.jps.Jps
But it's not there?
So, I used top instead and found out the PID 5730.
Then I called jstack to get the thread dump:
$ sudo jstack -l 5730
5730: Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding
What's going on? :-(
I already tried to export CATALINA_TMPDIR as described in Jstack and Jstat stopped working with upgrade to JDK6u23 but that didn't change anything:
$ export CATALINA_TMPDIR=/tmp
$ sudo /etc/init.d/tomcat6 restart
* Stopping Tomcat servlet engine tomcat6
...done.
* Starting Tomcat servlet engine tomcat6
...done.
$ sudo jstack -l 5934 // new PID after restart
5934: Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding
Update:
I also tried sudo -u tomcat6 jstack -l -F 5730 > threaddumpexceptions2.txt but it only gives me tons of exceptions on the console.
I got it working by doing two things:
Changed call to: sudo -u tomcat6 jstack -J-d64 -m pid
Replaced OpenJDK with Sun's original sun-6-jdk and sun-6-jre packages
Explanation for part 1: I switched to 64-bit mode, used sudo and run the command as Tomcat user.
Note: Part 2 might not be necessary. For some users it seems like part 1 is enough. In fact, try to add just the sudo command first. It might already do the trick.
I think you need to run jstack as the same user that runs the Tomcat process. Note also that jps only returns processes for the current user. You would get the pid for the Tomcat process by running jps with sudo or as the Tomcat process user.
This bug report may also be useful: https://bugs.launchpad.net/ubuntu/+source/sun-java6/+bug/597098
#Valmar, I find the same topic post here.
Unable to get thread dump? Any ideas why my app blocks?
It seems the workaround is sudo -u tomcat6 kill -3 <pid>.
Try to switch to process user and then use jstack:
sudo -u {process user} jstack > dump
This also worked for me:
sudo -u tomcat6 kill -3 pid
It looks like nothing happens but when you look in the logs the stacks are there. They look like exceptions if your not expecting them.
I find it useful to use something like 'ps -eo pid,user,command | grep java' to find the actual java command being used, then use the directory to find the matching jstack etc.
# ps -eo user,command | grep '[j]ava' | cut -d' ' -f1
someuser /usr/lib/jvm/java/bin/java
# /usr/lib/jvm/java/bin/java -version
java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)
So its 64-bit, running as 'someuser'. su to that user and run run jstack etc. from that same directory. (ie. /usr/lib/jvm/java/bin/jstack
Useful when you're on a server with various different installations / implementations of Java.
For Tomcat users having this issue, check your catalina.out log file.
I was having the same problems "22693: Unable to open socket file: target process not responding or HotSpot VM not loaded". I gave up and was trying to find anything about what happened before it locked up, but then there was the jstack output in the log file.
I had same problem, but none of below solution worked for me:
jstack <pid>
jstack -J-d64 -m <pid>
sudo -u <user> jstack ...
I finally upgraded JDK from jdk1.6.0_24 to jdk1.7.0_67 and every things worked.
For those finding this answer six years after it was asked and they are on CentOS 7 note that SELinux will stop jmap from writing the heap dumps as, out of the box, it will deny writing to a socket unless the directory has the type tomcat_tmp_t.
In my case, I write my heap dumps under /usr/share/tomcat/.jmap. This directory is owned by my runtime user.
Therefore to allow jmap to write to this directory:
semanage fcontext -a -t tomcat_tmp_t "/usr/share/tomcat/.jmap(/.*)?"
restorecon /usr/share/tomcat -vR
Which allows us to then run, as our tomcat user:
jmap -dump:format=b,file=/usr/share/tomcat/.jmap/tomcat-`date +%s`.bin <pid>
My problem was, I ran the process by the terminal. Then for testing Its jstack, I paused the process by ctrl+z. The process was not able to respond. To solve this problem, I resumed the process by fg and checked its jstack by another terminal.