JAVA调试原理、远程调试案例、maven启动springboot调试模式、调试 CAS 服务器(藏在 build.cmd debug 里的原理)

在这里插入图片描述

Java 调试原理

Java平台调试体系结构(Java Platform Debugger Architecture,JPDA)

参考

  1. Java黑科技之源:JVMTI完全解读
  2. Java调试原理初探

# JPDA体系概述

  • Java程序是运行在 JVM 上的
  • 调试java程序,事实上就是 向虚拟机请求其当前的运行状态
  • JPDA 就是虚拟机提供的 一整套用于 java 调试的 工具 和 接口

JPDA可以分为三个部分

  • Java虚拟机 工具接口(JVMTI,JVM Tool Interface)

  • Java调试线 协议(JDWP,Java Debug Wire Protocol )

  • Java 调试接口(JDI,Java Debug Interface)。

JPDA层次关系在这里插入图片描述

远程调试案例

1. 创建一个java项目,并写一个简单类

项目名 remote-debug-java

import java.util.Date;

public class DeadCycled {
    public static void main(String[] args) {
        boolean cycle = true ;
        boolean print = true ;
        while (cycle) {
            if(print) {
                System.out.println(new Date());
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

2. 打包成可执行 jar 包

参考:IDEA–生成jar包并且导出jar包

普通 java 项目,可以直接点 debug 就可执行了
(这是因为,开发工具帮你配置好了。)
在这里插入图片描述

而我们现在要手动配置

  • 生成可执行 jar 包
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

执行 jar 包 ,同时启动 debug 服务

参考:java实现远程调试

执行 jar 包命令

java -jar remote-debug-java.jar

在这里插入图片描述
而我们现在要启动 debug 服务器 (开启debug接口)

所以,先关了 ctrl + c

重新输入命令

java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5006 -jar remote-debug-java.jar

在这里插入图片描述
新命令运行后,控制台会显示,开启了 5006 端口

这就是 debug 服务端的端口。
后面只需要用客户端连接上端口,即可实现远程调试


必要说明

  • jdk1.7版本之前,命令为:
    java -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=y -jar xxx.jar
    1.7版本之后
    可仍然使用之前的命令: java -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=y -jar xxx.jar
    新命令
    java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 -jar test.jar

  • 命令参数详解(新命令为例)
    java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 -jar test.jar

    1. -Xdebug:通知JVM工作在debug模式下
    2. -Xrunjdwp:通知JVM使用(java debug wire protocol)来运行调试环境;
    3. transport:监听Socket端口连接方式
      (也可以dt_shmem共享内存方式,但限于windows机器,并且服务提供端和调试端只能位于同一台机);
    4. server:server=y表示当前是调试服务端,=n表示当前是调试客户端
      如果你想将当前应用作为被调试应用,设置该值为 y;
      如果你想将当前应用作为客户端,作为调试的发起者,设置该值为 n。
    5. suspend:suspend=n表示启动时不中断,一般用于设置主动连接;suspend=y表示启 动时就进入调试模式,一般用于被动连接;

      主动连接调试
      服务端配置监控端口,本地IDE连接远程监听端口进行调试,一般调试问题用这种方式。
      被动连接调试
      本地IDE监听某端口,等待远程连接本地端口。一般用于远程服务启动不了,启动时连接到本地调试分析。

  • 现在启动的是端口的提供者,我们称为 debug 服务端
    (接下来,启动 debug 客户端)

注意:这个服务端、客户端是相对的。
如果是 idea开发工具在监听,那么idea是服务端。
而现在,是 启动的程序在监听,所以启动的程序是服务端,idea 是客户端。

因此,响应的,程序的 server=y, 而(下面启动的)idea 的 server=n

debug 客户端 启动

以 idea 为例

(eclipse 类似,甚至更简单,可参考:https://www.cnblogs.com/wwywwy/p/9626078.html

用 idea 打开 jar 包的源码(不是源码,调试会异常哦~)

在这里插入图片描述
在这里插入图片描述
(下图)生成的命令预览,是 debug 服务的命令预览!
(即 jar 包 添加这个命令,可以开启服务器)
在这里插入图片描述
在这里插入图片描述

点击后,可以看到,程序暂停了,并且 idea 进入了 debug 界面。
说明 debug 客户端远程连接成功!

在这里插入图片描述

debug 客户端 断开

在这里插入图片描述

其他形式的 debug 服务端

参考:IntelliJ IDEA远程调试运行中的JAVA程序/项目

  1. 普通java程序配置
    示例:java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5006 -jar chess-server.jar

  2. tomcat中web项目配置
    在tomcat的 bin 目录中,新建 setenv.sh 文件,输入:
    CATALINA_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5006"

  3. 如果是windows系统,新建 setenv.bat 文件,输入:
    SET CATALINA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5006
    tomcat启动后会自动调用setenv文件,进行jvm参数设置

简单的 java 程序 远程调试

done~
在这里插入图片描述

maven 启动 springboot 的 debug 模式

参考:

有的项目需要命令行启动,每次到 target 目录下输入命令行很麻烦。

maven 提供了 操作 springboot 的命令行(其实是操作 java)

仔细看 springboot 的 pom.xml 文件 插件 部分。

都会有 spring-boot-maven-plugin 这个插件

可以用 maven 命令 操作 springboot

比如

我们先在 idea 开启一个 debug 的监听模式服务器
在这里插入图片描述
开启 debug 客户端的方法有两种。

  1. 可以在 项目根目录 输入下面命令,启动 springboot 的调试模式。

    mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=n,suspend=y,address=5005"
    

    注意,这时候是客户端,server=n

  2. 或者在 pom 文件中就写好了 jvm 参数

    <project>
      ...
      <build>
        ...
        <plugins>
          ...
          <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>2.2.5.RELEASE</version>
            <configuration>
              <jvmArguments>
                -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
              </jvmArguments>
            </configuration>
            ...
          </plugin>
          ...
        </plugins>
        ...
      </build>
      ...
    </project>
    

    在这里插入图片描述

两种客户端,只要一开启,就会被 服务端监听到,从而进入 debug 模式。

当然,你也可以让程序作为服务端,idea 作为客户端,道理一样,就换一下 server,和启动的顺序

debug启动 CAS 服务

有了前面的 铺垫,启动 cas 服务的debug 模式是水到渠成的。

这个项目作为例子:github 服务端 : https://github.com/LawssssCat/v-cas

更爽的是,cas 官方还提供了更简便的方法启动 debug 模式

只需要在 项目根目录执行下面指令:

#我这个是window系统,所以使用的是cmd
build.cmd debug
# linux 系统是 build.sh debug

测试的监听端口号为5000
在这里插入图片描述

注意:这时候是 应用为服务端
因此,下面我们开启 idea 作为 debug 的客户端连接上程序

添加debug调试 客户端

在这里插入图片描述

在这里插入图片描述

弄好配置后,开启debug ,就能看到连上了 的提示。

在这里插入图片描述

如果在相应的处理器上加断点。会开始调试

在这里插入图片描述

原理

打开build.cmd文件,大家可以看到下面这句话
在这里插入图片描述

:debug
    call:package %1 %2 %3 & java %JAVA_ARGS% -Xdebug -Xrunjdwp:transport=dt_socket,address=5000,server=y,suspend=n -jar target/cas.war
@goto:eof

命令解释

可以看成两个命令:

  1. mvn clean package
    (解释:maven 把项目清理,然后打包)
  2. java -Xms500m -Xmx1g -Xdebug -Xrunjdwp:transport=dt_socket,address=5000,server=y,suspend=n -jar target/cas.war
    (解释:运行 target 目录下 cas.war 文件,同时设定一些参数,包括 开启 debug 服务端)

其他一些命令的解释

  • : 批处理标签引导符
  • % 批处理变量引导符
  • CALL 从另一个批处理程序调用这一个。

参考:windows CMD命令大全及详细解释和语法

发布了501 篇原创文章 · 获赞 112 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/LawssssCat/article/details/105002822