运行和调试 Java

Visual Studio Code 允许您通过 Debugger for Java 扩展调试 Java 应用程序。它是一个基于 Java Debug Server 的轻量级 Java 调试器,扩展了 Language Support for Java™ by Red Hat

以下是支持的调试功能列表:

  • 启动/附加
  • 断点
  • 异常
  • 暂停 & 继续
  • 步入/步出/步过
  • 变量
  • 调用堆栈
  • 线程
  • 调试控制台
  • 评估
  • 热代码替换

Java调试器是一个开源项目,欢迎贡献者通过GitHub仓库进行协作:

如果您在使用以下功能时遇到任何问题,可以通过提交一个issue来联系我们。

安装

要在Visual Studio Code中获得完整的Java语言支持,您可以安装Java扩展包,其中包括Java调试器扩展。

安装Java扩展包

有关如何开始使用扩展包的详细信息,您可以查看Java入门教程。

配置

默认情况下,调试器将开箱即用地运行,通过自动找到主类并在内存中生成默认的启动配置来启动您的应用程序。

如果您想自定义并持久化您的启动配置,您可以在运行和调试视图中选择创建launch.json文件链接。

调试菜单

launch.json 文件位于工作区(项目根文件夹)中的 .vscode 文件夹中。

有关如何创建launch.json的更多详细信息,请阅读启动配置;有关Java配置选项的更多详细信息,您可以阅读配置选项

运行和调试

调试器扩展提供了多种方式来运行和调试您的Java应用程序。

从CodeLens运行

你会在main()函数的CodeLens上找到运行|调试

CodeLens

从编辑器菜单运行

另一种开始调试的方法是从顶部编辑器标题栏中选择运行Java调试Java菜单。

EditorMenu

通过按下F5运行

按下 F5,调试器将自动找到项目的入口点并开始调试。你也可以从 VS Code 侧边栏的 运行和调试 视图中启动调试会话。更多信息请参见 在 VS Code 中调试

调试单个文件

除了支持调试由构建工具管理的Java项目外,VS Code还支持调试没有任何项目的单个Java文件。

调试会话输入

VS Code 中的默认调试控制台不支持输入。如果你的程序需要从终端获取输入,你可以在 VS Code 中使用集成终端(⌃` (Windows, Linux Ctrl+`))或使用外部终端来启动它。你也可以使用用户设置 java.debug.settings.console 来为所有 Java 调试会话配置一个全局控制台。

断点

Java调试器支持各种断点,例如行断点、条件断点、数据断点、日志点。

断点 - 条件断点

借助表达式评估,调试器还支持条件断点。您可以将断点设置为在表达式评估为真时中断。

断点 - 数据断点

你可以在变量改变其值时让调试器中断。请注意,数据断点只能在调试会话中设置。这意味着你需要先启动你的应用程序并在常规断点上中断。然后你可以在VARIABLES视图中选择一个字段并设置数据断点。

数据断点

断点 - 日志点

Logpoints 也受到 Java 调试器的支持。Logpoints 允许您在不编辑代码的情况下将输出发送到调试控制台。它们与断点不同,因为它们不会停止应用程序的执行流程。

断点 - 触发的断点

触发的断点是在另一个断点被命中后自动启用的断点。在诊断仅在特定前提条件下发生的代码故障时,它们非常有用。

可以通过右键单击符号边距,选择添加触发断点,然后选择启用该断点的其他断点来设置触发断点。

表达式评估

调试器还允许您在WATCH窗口以及调试控制台中评估表达式。

热代码替换

调试器支持的另一个高级功能是“热代码”替换。热代码替换(HCR)是一种调试技术,通过该技术,Java调试器通过调试通道将类更改传输到另一个Java虚拟机(JVM)。HCR促进了实验性开发,并鼓励迭代试错编码。有了这个新功能,您可以启动调试会话并在开发环境中更改Java文件,调试器将替换正在运行的JVM中的代码。无需重新启动,这就是为什么它被称为“热”的原因。以下是如何在VS Code中使用Java调试器的HCR的示例。

您可以使用调试设置 java.debug.settings.hotCodeReplace 来控制如何触发热代码替换。可能的设置值为:

  • manual - 点击工具栏以应用更改(默认)。
  • auto - 编译后自动应用更改。
  • never - 禁用热代码替换。

步骤过滤

扩展支持步骤过滤器,用于过滤掉在调试时您不想看到或逐步执行的类型。通过此功能,您可以在launch.json中配置要过滤的包,以便在逐步执行时跳过它们。

配置选项

有许多选项和设置可用于配置调试器。例如,使用启动选项可以轻松配置JVM参数和环境变量。

请查阅Language Support for Java™ by Red Hat扩展的文档,以获取有关设置项目的帮助。

对于许多常用的设置,VS Code Java Debugger Configuration 中提供了示例。该文档解释了Java调试器如何自动为您生成配置,以及如果您需要修改它们,如何使用主类、不同的参数、环境、附加到其他Java进程以及使用更高级的功能。

以下是LaunchAttach可用的所有配置。有关如何编写launch.json文件的更多信息,请参阅调试

启动

  • mainClass(必需)- 程序的完全限定类名(例如 [java 模块名/]com.xyz.MainApp)或程序入口的 java 文件路径。
  • args - 传递给程序的命令行参数。使用"${command:SpecifyProgramArgs}"来提示输入程序参数。它接受一个字符串或字符串数组。
  • sourcePaths - 程序的额外源目录。调试器默认从项目设置中查找源代码。此选项允许调试器在额外目录中查找源代码。
  • modulePaths - 用于启动JVM的模块路径。如果未指定,调试器将自动从当前项目中解析。
    • $Auto - 自动解析当前项目的模块路径。
    • $Runtime - 当前项目“runtime”范围内的模块路径。
    • $Test - 当前项目“test”范围内的模块路径。
    • !/path/to/exclude - 从模块路径中排除指定路径。
    • /path/to/append - 将指定路径附加到模块路径中。
  • classPaths - 用于启动JVM的类路径。如果未指定,调试器将自动从当前项目中解析。
    • $Auto - 自动解析当前项目的类路径。
    • $Runtime - 当前项目中“runtime”范围内的类路径。
    • $Test - 当前项目中“test”范围内的类路径。
    • !/path/to/exclude - 从类路径中排除指定的路径。
    • /path/to/append - 将指定的路径追加到类路径中。
  • encoding - JVM 的 file.encoding 设置。如果未指定,将使用 'UTF-8'。可能的取值可以在 支持的编码 中找到。
  • vmArgs - JVM的额外选项和系统属性(例如 -Xms -Xmx -D=),它接受字符串或字符串数组。
  • projectName - 调试器在其中搜索类的首选项目。不同的项目中可能存在重复的类名。此设置在调试器启动程序时查找指定的主类时也有效。当工作空间中有多个Java项目时,这是必需的,否则表达式评估和条件断点可能无法工作。
  • cwd - 程序的工作目录。默认为 ${workspaceFolder}
  • env - 程序的额外环境变量。
  • envFile - 包含环境变量定义的文件的绝对路径。
  • stopOnEntry - 启动后自动暂停程序。
  • console - 指定用于启动程序的控制台。如果未指定,则使用java.debug.settings.console用户设置中指定的控制台。
    • internalConsole - VS Code 调试控制台(不支持输入流)。
    • integratedTerminal - VS Code 集成终端。
    • externalTerminal - 可以在用户设置中配置的外部终端。
  • shortenCommandLine - 当项目具有长类路径或大的虚拟机参数时,启动程序的命令行可能会超过操作系统允许的最大命令行字符串限制。此配置项提供了多种方法来缩短命令行。默认为auto
    • none - 使用标准命令行 'java {options} classname {args}' 启动程序。
    • jarmanifest - 将类路径参数生成到一个临时的 classpath.jar 文件中,并使用命令行 'java -cp classpath.jar classname {args}' 启动程序。
    • argfile - 将类路径参数生成到一个临时的参数文件中,并使用命令行 'java @argfile {args}' 启动程序。此值仅适用于 Java 9 及以上版本。
    • auto - 自动检测命令行长度,并通过适当的方法决定是否缩短命令行。
  • stepFilters - 在单步执行时跳过指定的类或方法。
    • classNameFilters - [已弃用 - 由 skipClasses 替代] 在单步执行时跳过指定的类。类名应为完全限定名。支持通配符。
    • skipClasses - 在单步执行时跳过指定的类。您可以使用内置变量如 '$JDK' 和 '$Libraries' 来跳过一组类,或者添加特定的类名表达式,例如 java.*, *.Foo
    • skipSynthetics - 在单步执行时跳过合成方法。
    • skipStaticInitializers - 在单步执行时跳过静态初始化方法。
    • skipConstructors - 在单步执行时跳过构造方法。

附加

  • hostName (必填) - 远程调试对象的主机名或IP地址。
  • port (必填) - 远程调试对象的调试端口。
  • processId - 使用进程选择器选择要附加的进程,或使用整数形式的进程ID。
    • ${command:PickJavaProcess} - 使用进程选择器选择要附加的进程。
    • 一个整数PID - 附加到指定的本地进程。
  • timeout - 重新连接前的超时值,以毫秒为单位(默认为30000毫秒)。
  • sourcePaths - 程序的额外源目录。调试器默认从项目设置中查找源代码。此选项允许调试器在额外目录中查找源代码。
  • projectName - 调试器在其中搜索类的首选项目。在不同的项目中可能存在重复的类名。当工作空间中有多个Java项目时,这是必需的,否则表达式评估和条件断点可能无法工作。
  • stepFilters - 在单步执行时跳过指定的类或方法。
    • classNameFilters - [已弃用 - 由 skipClasses 替代] 在单步执行时跳过指定的类。类名应为完全限定名。支持通配符。
    • skipClasses - 在单步执行时跳过指定的类。您可以使用内置变量如 '$JDK' 和 '$Libraries' 来跳过一组类,或者添加特定的类名表达式,例如 java.*, *.Foo
    • skipSynthetics - 在单步执行时跳过合成方法。
    • skipStaticInitializers - 在单步执行时跳过静态初始化方法。
    • skipConstructors - 在单步执行时跳过构造方法。

用户设置

  • java.debug.logLevel: 发送到VS Code的调试器日志的最低级别,默认为warn
  • java.debug.settings.showHex: 在变量中以十六进制格式显示数字,默认为false
  • java.debug.settings.showStaticVariables: 在变量中显示静态变量,默认为false
  • java.debug.settings.showQualifiedNames: 在变量中显示完全限定的类名,默认为false
  • java.debug.settings.showLogicalStructure: 在变量中显示集合和映射类的逻辑结构,默认为true
  • java.debug.settings.showToString: 在变量中显示所有重写了'toString'方法的类的'toString()'值,默认为true
  • java.debug.settings.maxStringLength: 在变量调试控制台中显示的字符串的最大长度。超过此限制的字符串将被截断。默认值为0,表示不进行截断。
  • java.debug.settings.hotCodeReplace: 在调试期间重新加载更改的Java类,默认为manual。确保Java语言支持扩展java.autobuild.enabled未被禁用。有关使用和限制的更多信息,请参阅热代码替换维基页面
    • manual - 点击工具栏以应用更改。
    • auto - 编译后自动应用更改。
    • never - 从不应用更改。
  • java.debug.settings.enableHotCodeReplace: 启用Java代码的热替换。确保VS Code Java的自动构建未被禁用。有关使用和限制的更多信息,请参阅热替换wiki页面
  • java.debug.settings.enableRunDebugCodeLens: 为主入口点上的运行和调试按钮启用CodeLens提供程序,默认为true
  • java.debug.settings.forceBuildBeforeLaunch: 在启动Java程序之前强制构建工作区,默认为true
  • java.debug.settings.console: 指定用于启动Java程序的控制台,默认为integratedTerminal。如果您想为特定的调试会话自定义控制台,请修改launch.json中的console配置。
    • internalConsole - VS Code调试控制台(不支持输入流)。
    • integratedTerminal - VS Code集成终端。
    • externalTerminal - 可以在用户设置中配置的外部终端。
  • java.debug.settings.exceptionBreakpoint.skipClasses: 在异常中断时跳过指定的类。您可以使用内置变量如'$JDK'和'$Libraries'来跳过一组类,或者添加特定的类名表达式,例如java.*, *.Foo
  • java.debug.settings.stepping.skipClasses: 在单步执行时跳过指定的类。您可以使用内置变量如'$JDK'和'$Libraries'来跳过一组类,或者添加特定的类名表达式,例如java.*, *.Foo
  • java.debug.settings.stepping.skipSynthetics: 在单步执行时跳过合成方法。
  • java.debug.settings.stepping.skipStaticInitializers: 在单步执行时跳过静态初始化方法。
  • java.debug.settings.stepping.skipConstructors: 在单步执行时跳过构造函数方法。
  • java.debug.settings.jdwp.limitOfVariablesPerJdwpRequest: 在一个JDWP请求中可以请求的最大变量或字段数。值越高,展开变量视图时调试对象被请求的频率就越低。同时,较大的数值可能导致JDWP请求超时。默认值为100。
  • java.debug.settings.jdwp.requestTimeout: 调试器与目标JVM通信时JDWP请求的超时时间(毫秒)。默认为3000。
  • java.debug.settings.vmArgs: 启动Java程序的默认虚拟机参数。例如,使用'-Xmx1G -ea'将堆大小增加到1 GB并启用断言。如果你想为特定的调试会话自定义虚拟机参数,可以修改launch.json中的'vmArgs'配置。
  • java.silentNotification: 控制是否可以使用通知来报告进度。如果为true,则使用状态栏来报告进度。默认为false

故障排除

如果您在使用调试器时遇到问题,可以在vscode-java-debug GitHub 仓库中找到详细的故障排除指南。

常见问题解释包括:

  • Java 语言支持扩展无法启动。
  • 构建失败,您要继续吗?
  • *.java 不在类路径上。只会报告语法错误。
  • 程序错误:无法找到或加载主类 X。
  • 程序抛出ClassNotFoundException。
  • 未能完成热代码替换。
  • 请在launch.json中指定远程调试对象的主机名和端口。
  • 评估失败。原因:无法评估,因为线程已恢复。
  • 找不到包含主方法的类。
  • 启动调试器时,没有为 vscode.java.startDebugSession 提供 delegateCommandHandler。
  • 未能解析类路径。
  • 不支持请求类型 "X"。仅支持 "launch" 和 "attach"。

反馈与问题

您可以在vscode-java-debug仓库中找到完整的问题列表。您可以提交错误或功能建议,并参与社区驱动的vscode-java-debug Gitter频道

下一步

继续阅读以了解以下内容:

  • 调试 - 了解如何在VS Code中使用调试器与您的项目进行任何语言的调试。

对于Java:

  • Java testing - 使用Java测试运行器扩展在VS Code中测试Java。
  • Java extensions - 了解VS Code中更多有用的Java扩展。