无源码调试 Jar 包
普通可执行 Jar 包
这里先以普通 jar 包为例。在 pom.xml 中的文件插件内容如下:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<!-- 这里是你的项目main函数所在的类的全限定名 -->
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
这里通过使用 mvn clean compile assembly:single
打包出一个可执行的 jar 包。通过压缩包可视化可以看到,里面已经完完全全包含了我们所需要的 class 文件了。
这样问题就很简单了,打开 IDEA 新建一个空的项目,在 File–Project Settings–Project 配置好 jdk 环境
并在左上角的 File–Project Settings–Libraries 直接添加这个 jar 包即可
添加完毕后类似这个效果
然后在 IDEA 右上角运行处编辑 Run/Debug Configuration,添加 Remote JVM Debug,配置可按需修改
然后在终端上先运行这个 jar 包
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar xxxx-with-dependencies.jar
在 IDEA 某个合适的位置下断点
此时访问合适的 web 路径即可触发断点,可像源码一样调试
其中如果在调试 Web 应用中,某个断点想要多次测试,但是常常发现断点一次触发后就不再触发了。可以参考 https://www.jetbrains.com/help/idea/using-breakpoints.html#suspend_policy 将 suspend 设置为 Thread 规则。
调试 SpringBoot 可执行 Jar 包
在 SpringBoot 中主要的 class 都是放在 BOOT-INF/classes 目录下,而 org 目录则是存放启动 SpringBoot 项目的 class,对于我们调试作用不大。META-INF 则是存放 maven 的 pom.xml 文件信息。
此时跟上面的步骤一样,新建一个空的项目,但是不能直接添加这个 jar 包,而是将 jar 包解压出来。我们需要添加的是 classes 文件夹下的所有编译类以及 lib 下的所有第三方 jar 包
结果如下,classes 的内容是项目源码编译出的 class
然后还是运行 jar 包
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar xxxx-with-dependencies.jar
之后一样的步骤,就可以正常调试了