环境
服务器:
- 操作系统:centos6
- jdk:1.7
- tomcat:8.5.9
本地:
- 操作系统:mac osx 10.11.6
- jdk:1.7
- intellij:2016.2
- tomcat:8.5.9(本地也需要下载tomcat)
应用调试步骤
java应用远程调试都是基于jpda体系,所以我们需要将tomcat通过jpda的方式启动,即可对tomcat进行远程调试。
一、服务端tomcat配置
假设服务端tomcat所在目录为:/etc/tomcat/
。对于tomcat来说,所有运行相关的脚本都位于bin文件夹下,而catalina.sh是启动tomcat最为核心的脚本。为了使得tomcat能够支持远程调试,我们需要设置jpda相关的参数,但是tomcat官方建议我们不要直接修改catalina.sh里面定义的参数,而是将自定义的参数值设置在setenv.sh脚本中,证据如下:
# Environment Variable Prerequisites
#
# Do not set the variables in this script. Instead put them into a script
# setenv.sh in CATALINA_BASE/bin to keep your customizations separate.
tomcat里定义的jpda参数有:
- JPDA_TRANSPORT:设置jpda传输方式,默认为dt_socket,此参数一般保持默认值即可。
- JPDA_ADDRESS:服务端jpda监听的地址和端口,默认为localhost:8000,即本地的8000端口。此参数需根据实际情况进行修改。比如在本文场景中,我们需要远程调试tomcat,所以不能监听在本地,否则外网无法访问。
- JPDA_SUSPEND:设置应用程序是否一启动就挂起,等待客户端调试器连接,默认为"n"也就是不挂起,若需要设置为挂起则修改为"y"。
- JPDA_OPTS:若用户设置了该参数,则脚本执行时会忽略上述三个参数,直接拿JPDA_OPTS的值作为jpda的启动参数。
默认情况下,tomcat的jpda启动配置为:
-agentlib:jdwp=transport=dt_socket,address=localhost:8000,server=y,suspend=n
我们需要根据自己的实际情况设置合适的参数,具体设置的步骤如下:
-
在bin文件夹下新建setenv.sh并编辑:
# cd /etc/tomcat/bin # vim setenv.sh
-
设置JPDA_ADDRESS的值为0.0.0.0:8000:
JPDA_ADDRESS=0.0.0.0:8000
保存退出。
-
以jpda的方式启动tomcat:
# ./catalina.sh jpda start
此时tomcat已经以jpda的方式启动,并且向外网开放了8000端口等待客户端发送调试命令。
二、Intellij配置
接下来我们需要配置intellij,具体步骤如下:
-
首先打开Run/Debug Configuration窗口:
-
点击左上角的➕号,添加一个Remote Tomcat:
-
填写Server配置项,需要配置的有配置名称、本地tomcat路径以及tomcat所在的host和开放的端口:
-
配置debug所需的参数。在本例中,由于我们在服务端的tomcat配置的是dt_socket,端口为8000,所以在这里我们也需要配置为socket和8000端口:
-
选择刚才的配置(比如在本例中为开发机),然后点击debug图标,打断点,开始远程调试:
调试tomcat源码
在某些情况下,我们需要调试tomcat自己的运行情况,比如为何应用里配置的listener没有加载成功,或者想研究tomcat的应用机制,这个时候,我们就需要直接调试tomcat的源码。
一、下载源码
俗话说,巧妇难为无米之炊,我们首先需要下载tomcat的源码。在本例中,我们tomcat的版本为8.5.9,下载地址请点击。下载成功后解压,我们假设源码目录位于:~/tomcat/
。
二、导入源码
我们需要将源码导入到intellij中,为接下来的调试打好基础。
-
下载下来的tomcat是一个ant工程,为了方便,我们首先将其转化为一个maven工程,这样我们就不需要关心依赖包的下载问题。我们在源码目录下新建pom.xml文件,pom的内容如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.apache.tomcat</groupId> <artifactId>Tomcat8.0</artifactId> <name>Tomcat8.0</name> <version>8.0</version> <build> <finalName>Tomcat8.0</finalName> <sourceDirectory>java</sourceDirectory> <testSourceDirectory>test</testSourceDirectory> <resources> <resource> <directory>java</directory> </resource> </resources> <testResources> <testResource> <directory>test</directory> </testResource> </testResources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3</version> <configuration> <encoding>UTF-8</encoding> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>ant</groupId> <artifactId>ant</artifactId> <version>1.7.0</version> </dependency> <dependency> <groupId>wsdl4j</groupId> <artifactId>wsdl4j</artifactId> <version>1.6.2</version> </dependency> <dependency> <groupId>javax.xml</groupId> <artifactId>jaxrpc</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>org.eclipse.jdt.core.compiler</groupId> <artifactId>ecj</artifactId> <version>4.5</version> </dependency> <!-- https://mvnrepository.com/artifact/org.easymock/easymock --> <dependency> <groupId>org.easymock</groupId> <artifactId>easymock</artifactId> <version>3.2</version> <scope>test</scope> </dependency> </dependencies> </project>
-
然后我们将源码导入到intellij中:
在弹出来的对话框中选择刚才源码所在的目录,并且作为Maven工程导入,即可导入成功。
为了避免待会执行test时出现问题,我们需要删除test/util/TestCookieFilter.java文件。
三、配置远程调试
配置步骤与第二部分介绍的配置步骤相同。唯一需要注意的是,服务端的tomcat在配置jpda参数时,可以将JPDA_SUSPEND设置为y,这样tomcat启动之后不会执行任何代码,而是挂起,直到客户端连上来后才会继续执行。
其他
如果存在服务端jpda已经启动,但是客户端无法连接的情况,请检查防火墙。