公司因为安全需要,没有开放java远程调试端口,记录下进docker在线调试java
基本点:
- pom文件maven-compiler-plugin配置正确
- DOCKERFILE里设置jvm变量开启调试端口
- jdb list看不了源码(但可以看行号和变量),需要手动把源码拷贝到docker后, jdb里use
网上搜到的jdb教程都是直接javac编译后调试. maven中其实也可以配置javac参数:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <configuration> <source>1.8</source> <target>1.8</target> <!-- 强制使用javac编译 --> <forceJavacCompilerUse>true</forceJavacCompilerUse> <debug>true</debug> <debuglevel>source,lines,vars</debuglevel> </configuration> </plugin>
效果就跟javac -g一样了 debug为true表示开启把调试信息加入编译后的classfile,debuglevel表示加入哪些信息到classfile,但此source不代表jdb list时能看到源码(估计是加类,方法等信息,没深究). lines代表行号,不加的话调试时会显示line(-1),看不到行号. vars代表变量信息
关于DOCKERFILE里设置jvm变量. 因为我使用的jetty docker,看它的教程和DOCKERFILE得知, 它会读取
JAVA_OPTIONS参数, 在执行java时将该参数设置到jvm. DOCKERFILE关键行:
ENV JAVA_OPTIONS="-Xms400m -Xmx400m -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8081"
开启8081为调试端口
有些docker,比如jetty-jre里是没有jdk的,只有jre,需要自己想办法把jdk加进去,才有jdb命令
- docker cp project/src/ <CONTAINER_ID>:/var/lib/jetty 把源码拷贝到docker里
- docker exec -it <CONTAINER_ID> /bin/bash进入docker的bash
- jdb -attach localhost:8081 attach到在线java程序
- use ./src/main/java use设置源码为java文件的父目录
- jdb那一套开始调试