Chan Chen Coding...

Java Web Application 远程调试

最近在开发java web application的时候,因为很多原因,无法对自己开发的项目在本地进行调试,常常需要进行远程调试,之前一直通过打logger的方式进行,每次都要重新部署,相当的痛苦,今天下午研究了以下,如果进行远程调试。

开发的web application是部署在tomcat上面的,那么问题就转化为如何调试tomcat。其实调试tomcat,本质上就是调试JVM。JVM的强大,从J2SE1.4.2开始,就实现了JPDA (Java Platform Debug Architecture)。

tomcat默认情况下,是没有启用jpda的,如果要启用,需要传入参数
-Xdebug -Xrunjdwp:transport=dt_socket, address=8000,server=y,suspend=y

那么问题是这些参数如何在tomcat启动的使用传入呢?这是时候,需要了解tomcat的启动脚本,在TOMCAT_HOME/bin

目录下,有三个脚本catalina.sh, startup.sh, 和 shutdown.sh。如果查看startup.sh和shutdown.sh,都是通过catalina.sh来启动的。脚本如下:

EXECUTABLE=catalina.sh

exec "$PRGDIR"/"$EXECUTABLE" start "$@"
于是,我们可以查看下catalina.sh的脚本是如何实现的。

#   JPDA_TRANSPORT  (Optional) JPDA transport used when the "jpda start"
#                   command is executed. The default is "dt_socket".
#
#   JPDA_ADDRESS    (Optional) Java runtime options used when the "jpda start"
#                   command is executed. The default is 8000.
#
#   JPDA_SUSPEND    (Optional) Java runtime options used when the "jpda start"
#                   command is executed. Specifies whether JVM should suspend
#                   execution immediately after startup. Default is "n".
#
#   JPDA_OPTS       (Optional) Java runtime options used when the "jpda start"
#                   command is executed. If used, JPDA_TRANSPORT, JPDA_ADDRESS,
#                   and JPDA_SUSPEND are ignored. Thus, all required jpda
#                   options MUST be specified. The default is:
#
#                   -agentlib:jdwp=transport=$JPDA_TRANSPORT,
#                       address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND

if [ "$1" = "jpda" ] ; then
  if [ -z "$JPDA_TRANSPORT" ]; then
    JPDA_TRANSPORT="dt_socket"
  fi  
  if [ -z "$JPDA_ADDRESS" ]; then
    JPDA_ADDRESS="8000"
  fi  
  if [ -z "$JPDA_SUSPEND" ]; then
    JPDA_SUSPEND="n"
  fi  
  if [ -z "$JPDA_OPTS" ]; then
    JPDA_OPTS="-agentlib:jdwp=transport=$JPDA_TRANSPORT,address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND"
  fi  
  CATALINA_OPTS="$CATALINA_OPTS $JPDA_OPTS"
  shift
fi

通过这个代码,我们可以看出,其实要启动jpda, 最主要的是要对JPDA_SUSPEND的值进行设置,由N改为Y。

借鉴start.sh的启动,在linux下,我们可以自己创建一个jpda.sh的脚本,用来启动开启debug模式的tomcat,具体脚本如下,黑体为修改部分。

os400=false
darwin=false
case "`uname`" in
CYGWIN*) cygwin=true;;
OS400*) os400=true;;
Darwin*) darwin=true;;
esac

# resolve links - $0 may be a softlink
PRG="$0"

while [ -h "$PRG" ] ; do
  ls=`ls -ld "$PRG"`
  link=`expr "$ls" : '.*-> \(.*\)$'`
  if expr "$link" : '/.*' > /dev/null; then
    PRG="$link"
  else
    PRG=`dirname "$PRG"`/"$link"
  fi
done
 
PRGDIR=`dirname "$PRG"`
EXECUTABLE=catalina.sh

# Check that target executable exists
if $os400; then
  # -x will Only work on the os400 if the files are: 
  # 1. owned by the user
  # 2. owned by the PRIMARY group of the user
  # this will not work if the user belongs in secondary groups
  eval
else
  if [ ! -x "$PRGDIR"/"$EXECUTABLE" ]; then
    echo "Cannot find $PRGDIR/$EXECUTABLE"
    echo "The file is absent or does not have execute permission"
    echo "This file is needed to run this program"
    exit 1
  fi
fi 

export JPDA_SUSPEND=y

exec "$PRGDIR"/"$EXECUTABLE" jpda start "$@"

 

在Eclipse中远程调试Tomcat

首先将Tomcat 5.5.26的源代码分为container connectors jasper servletapi build五个项目,导入到Eclipse中。启动相关的代码主要在container中,就以它为当前项目,打开”Debug Configurations“对话框。

然后创建一个”Remote Java Application“,Connection Type选择”Standard (Socket Attach)“,Host填写localhost(Tomcat所在的主机地址),Port填写8000。最后点击”Apply“保存。

Eclipse的Debug Configurations对话框中配置远程调试

 

首先确保已经执行了jpda.bat,Tomcat正在等待调试器连接;然后执行上述的Debug Configuration,Eclipse就可以连上Tomcat。

 

Tomcat的启动是从Bootstrap的main方法开始,我在第一行代码处设置了断点,Tomcat的启动就停在了这一行:

 

断点调试Tomcat的启动过程

 

接着,让Tomcat继续执行,我们可以看到,控制台输出了启动信息。

Tomcat在JPDA模式下继续启动



-----------------------------------------------------
Silence, the way to avoid many problems;
Smile, the way to solve many problems;

posted on 2013-05-05 16:49 Chan Chen 阅读(1604) 评论(0)  编辑  收藏 所属分类: Linux


只有注册用户登录后才能发表评论。


网站导航: