远程调试java代码(分析一个resteasy的例子)
本文通过一个demo项目来学习java的remote debug的方法。这个demo项目在这里:
HashMapResource
这个demo介绍ResteasyJackson2Provider
的使用方法,同时通过这个过程学习远程调试方法。然后查看这个PR里面引入的HashMapResource
这个class:
可以看到这个class的map()
方法是接受一个HashMap
类型的params
参数。并且接受的数据请求格式是json
格式。
因此,访问上面的服务,就可以验证resteasy-jackson2-provider
是否工作。这个依赖被添加到了pom.xml
里面:
接下来是设置断点,我们把断点设置在项目代码之外,直接设置在resteasy
的ResteasyJackson2Provider
的方法里:
这样,当我们运行起来服务,访问服务的时候,服务器端应该是会跳到这个class的断点来,因为最终处理服务的class是这个。
设置好断点以后,接下来就是用「远程debug」的形式来启动jetty服务,下面是架构:
上面的架构里面可以看到服务是如何对应到代码断点的。为了实现这个流程,我们需要执行下面的maven命令来启动服务:
$ export MAVEN_OPTS='-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005'
$ mvn jetty:run
执行效果如下:
此时可以看到jetty服务进入了debug模式,并且在等待远程调试连接,连接端口是5005
。此时在intellij这边设置remote debug:
如上所示,我们在intellij里面添加一个remote debug
的方案配置,并点击OK
,添加结果如下:
添加完成后,我们就可以使用这个profile,然后开始进行调试:
此时可以看到这个remote debug
连接了「服务端」那边的5005
端口:
此时查看服务端这边,也可以看到服务继续启动过程并完成了启动:
此时我们以debug的形式运行HashMapResource
里面的main()
方法来访问这个服务:
此时可以看到通过访问服务,服务端走到了我们设置的断点处:
注意上面的断点的stacktrace
,可以看到触发writeTo()
方法的是客户端这边:
因此也就是把客户端请求的HashMap
的数据给序列化成String
类型:
注意之所以断点能停在writeTo()
方法这里,是因为我们上面使用debug
的方法来启动了main()
方法,所以在客户端执行的过程中的断点就会停下来。这个和我们服务端的debug运行模式没关系,因为此时「客户端」还没有把数据发给「服务端」。
完成了上面的分析以后,我们继续运行代码逻辑,这个时候「客户端」会把请求发给「服务端」,此时可以看到断点停在了readFrom()
的方法上:
而且从stacktrace可以看到此时的断点是停在「服务端」这边的逻辑之上。
通过上面的分析过程,我们验证了确实是resteasy-jackson2-provider
这个模块在起作用。
同时我们也学习了remote debug的使用方式。