其实如果广告是Java程序,或者是Spring boot,用IDEA调试都是很简单的事情。
不过最近在维护一个老项目,用的是tomcat8+Java1.7版本,所以本地的开发环境也需要一致。
就用docker搭了一个docker + tomcat环境。
开发之前的第一步,自然是整好调试环境,以便在出错时对程序运行状态和变量有清晰的了解。
以下便是我具体的docker环境。
. ├── docker-compose.yml 容器启动配置文件 ├── conf 配置目录 │ └── server.xml Tomcat站点配置文件 └── www 站点根目录 ├── awaimai 站点1根目录 │ ├── src 站点1 Java源码 │ └── target 站点1 编译目录 └── localhost 站点2根目录
这样的结构可以一个命令:
$ docker-compose up
就能启动服务,并且在所有操作系统上都保持一直。
(这里省略nginx、mysql、redis、activemq等服务目录)
这是docker搭建环境的一键配置文件,具体内容如下(省略MySQL服务):
version: "3" services: tomcat: image: tomcat:8.5.27 ports: - "8080:8080" - "5005:5005" volumes: - ./www:/www:rw - ./conf/server.xml:/usr/local/tomcat/conf/server.xml:ro environment: TZ: Asia/Shanghai JPDA_ADDRESS: 5005 JPDA_TRANSPORT: dt_socket command: ["catalina.sh", "jpda", "run"] networks: - default # 需要nginx、mysql、redis、activemq配置都可以在这里加上 networks: default:
其中,
8080端口是供浏览器访问的端口,我们暴露到主机,这样就能在主机中访问容器的服务。
5005端口是JPDA使用的调试端口,因为我们的IDEA IDE是在主机,所以也需要暴露这个端口到主机。
接着我们还需要在容器中指定两个环境变量,JPDA_ADDRESS: 5005和JPDA_TRANSPORT: dt_socket,
5005是JPDA使用的端口,我们已经暴露给主机了,所以主机调试用的就是这个端口,socket是JPDA的连接方式。
最后,我们用command: ["catalina.sh", "jpda", "run"],以JPDA方式启动 Tomcat。
这样容器就配置成可调试的了。
顺便再贴上我 server.xml 配置的配置,
<Host name="www.awaimai.com" appBase="/www/awaimai/target" unpackWARs="true" autoDeploy="true" reloadable="true"> </Host>
我的Java代码是在本地的 ./www/awaimai/src/main 目录下,映射到容器的/www/awaimai/src/main目录下。
因为 tomcat 只是运行编译之后的代码,所以源码映射还是不映射到容器都无所谓,
因为我这里直接把 ./www 目录挂过去了,所以目录是对应的。
编译后的的代码在本地 ./www/awaimai/target 目录,映射到容器的 /www/awaimai/target 目录下。
一般来说,target 目录下会有 .war 文件,tomcat 会自动解压为一个目录。
IDEA菜单:Run -> Edit Configurations...
点击左上角的+号,选择Remote,
然后填上Host和port,这里的Host是 server.xml 中指定的Host,Port是jpda的端口。
因为我们用的是域名,所以还需要在主机的 /etc/hosts 文件中加上这样一行:
127.0.0.1 www.awaimai.com这样我们在浏览器中访问:www.awaimai.com:8080,就能访问容器中tomcat服务了。
我的配置如下图:
其实就是改了Host和Port。
然后在IDEA中选择菜单:Run -> Debug myDebug,Debugger的variables窗口显示:
Connected to the target VM, address: 'www.awaimai.com:5050', transport: 'socket'
说明IDEA已经连上docker容器的jpda了。
在代码的控制器中打一个断点。
@RequestMapping(value = "/login.do", method = RequestMethod.GET) public ModelAndView login(HttpServletRequest request) { ModelAndView mav = new ModelAndView("login"); return mav; }
比如我在第3行打了一个断点,然后在浏览器中访问:
www.awaimai.com:8080/login.do
在IDEA中程序就会停止在断点处,接下来就随便操作了。
参考资料: