配置tomcat环境变量

cd $TOMCAT_HOME/bin/

添加或编辑`setenv.sh`

setenv.sh 文件内容

#!/bin/sh

CATALINA_OPTS="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -XX:+PrintGCDetails -Xloggc:gc.log -XX:+DisableExplicitGC -Xdebug -Xrunjdwp:transport=dt_socket,address=8888,server=y,suspend=n"

参数说明

-Xdebug

表示开启debug

address

调试监听的地址和端口。直接写的话,就是端口,也可以是 address=IP:port

如果servery,那address可以不必设置. 如果servern,就一定要设置address.

server

debugger进程是否以监听的方式启动.

如果servery,那address可以不必设置.否则就一定要设置address.

如果servery,而且address又没有设置(如果设置了address,则以address为准),那比较麻烦。

先查出应用监听的所有端口:

➜  ~  lsof -p 16995 -Pan -i
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /home/yang/.gvfs
      Output information may be incomplete.
COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
java    16995 yang    5u  IPv4 1382347      0t0  TCP *:56969 (LISTEN)
java    16995 yang   50u  IPv6 1382352      0t0  TCP *:8080 (LISTEN)
java    16995 yang   51u  IPv6 1382353      0t0  TCP *:8009 (LISTEN)
java    16995 yang   57u  IPv6 1382359      0t0  TCP 127.0.0.1:8005 (LISTEN)
➜  ~

然后去掉tomcat自身监听的端口(可在server.xml里找到),剩下的那个端口,就是debugger server的监听端口了(这里是56969端口)。 然后执行:

➜  ~  jdb -attach localhost:56969
设置未捕获的java.lang.Throwable
设置延迟的未捕获的java.lang.Throwable
正在初始化jdb...
>

注意,执行完这句后,就会在应用的标准输出里,会打印如何类似语句:

Listening for transport dt_socket at address: 42524

后面的端口,是随机的,这个是新的监听端口.也可以连接到42524

这时,就可以使用IDE连接这个端口,来进行调试了。

这样子的好处是:端口不是固定的,而是随机的。

transport

建立通信的方式.

dt_socket

可用于Solaris, Linux, and Microsoft Windows platforms

dt_shmem

只能用于Microsoft Windows platform

连接调试 debugger 服务器

IDEA

Run -> Edit Configuration -> + -> Remote

然后填写`host`(debugger 服务器所在主机,即tomcat运行的那个主机)和`port`(监听端口)的值就可以了

参考资料

  1. Oracle JavaSE Transports

  2. 命令行帮助

➜  ~  java -agentlib:jdwp=help
               Java Debugger JDWP Agent Library
               --------------------------------

  (see http://java.sun.com/products/jpda for more information)

jdwp usage: java -agentlib:jdwp=[help]|[<option>=<value>, ...]

Option Name and Value            Description                       Default
---------------------            -----------                       -------
suspend=y|n                      wait on startup?                  y
transport=<name>                 transport spec                    none
address=<listen/attach address>  transport spec                    ""
server=y|n                       listen for debugger?              n
launch=<command line>            run debugger on event             none
onthrow=<exception name>         debug on throw                    none
onuncaught=y|n                   debug on any uncaught?            n
timeout=<timeout value>          for listen/attach in milliseconds n
mutf8=y|n                        output modified utf-8             n
quiet=y|n                        control over terminal messages    n

Obsolete Options
----------------
strict=y|n
stdalloc=y|n

Examples
--------
  - Using sockets connect to a debugger at a specific address:
    java -agentlib:jdwp=transport=dt_socket,address=localhost:8000 ...
  - Using sockets listen for a debugger to attach:
    java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y ...

Notes
-----
  - A timeout value of 0 (the default) is no timeout.

Warnings
--------
  - The older -Xrunjdwp interface can still be used, but will be removed in
    a future release, for example:
        java -Xdebug -Xrunjdwp:[help]|[<option>=<value>, ...]

➜  ~