模块 jdk.jdi

接口 VirtualMachineManager


public interface VirtualMachineManager
目标虚拟机的连接管理器。 VirtualMachineManager 允许一个应用程序调试多个目标 VM。 (请注意,不支持相反的情况;目标 VM 只能由一个调试器应用程序进行调试。)此接口包含管理与远程目标 VM 的连接以及获取可用目标 VM 的VirtualMachine 镜像的方法。

可以使用几个不同的 Connector 对象之一进行连接。每个连接器封装了一种将调试器与目标 VM 连接的不同方式。

VirtualMachineManager 支持将调试器连接到虚拟机的许多不同场景。下表列出了四个示例。这些示例使用 Sun 实现中的命令行语法。一些 Connector 实现可能需要与下面介绍的处理略有不同。

调试器连接虚拟机的四种场景"
设想 Description
调试器启动目标 VM(最简单、最常见的场景) 调试器调用默认连接器的 LaunchingConnector.launch(java.util.Map) 方法,通过 defaultConnector() 获得。启动目标 VM,并在该 VM 和调试器之间建立连接。 VirtualMachine 镜像被返回。

或者,为了获得更多控制

调试器附加到以前运行的 VM
  • 使用选项 -agentlib:jdwp=transport=xxx,server=y 启动目标 VM
  • 目标 VM 生成并输出特定于传输的地址,它将在该地址监听连接。
  • 调试器启动。调试器在 attachingConnectors() 返回的列表中选择一个连接器,该连接器与名称为“xxx”的传输相匹配。
  • 调试器向最终用户提供默认连接器参数(通过 Connector.defaultArguments() 获得),允许用户填写目标 VM 生成的传输特定地址。
  • 调试器调用所选对象的 AttachingConnector.attach(java.util.Map) 方法以附加到目标 VM。 VirtualMachine 镜像被返回。
目标 VM 附加到先前运行的调试器
目标 VM 启动调试器(有时称为“即时”调试)
  • 目标 VM 使用选项 -agentlib:jdwp=launch=cmdline,onuncaught=y,transport=xxx,server=y 启动
  • 稍后,目标 VM 中会抛出一个未捕获的异常。目标 VM 生成特定于传输的地址,它将在该地址监听连接。
  • 目标 VM 启动调试器,将以下项目连接在一起(以空格分隔)以形成命令行:
    • 发射=值
    • 运输=值
    • VM 正在监听调试器连接的生成的传输特定地址。
  • 启动后,调试器会在 attachingConnectors() 返回的列表中选择一个连接器,该连接器与名称为“xxx”的传输相匹配。
  • 调试器更改默认连接器参数(通过 Connector.defaultArguments() 获取)以指定 VM 监听的传输特定地址。可选地,可以将其他连接器参数呈现给用户。
  • 调试器调用所选对象的 AttachingConnector.attach(java.util.Map) 方法以附加到目标 VM。 VirtualMachine 镜像被返回。

连接器是在启动时创建的。也就是说,它们是在第一次调用 Bootstrap.virtualMachineManager() 时创建的。可以通过调用 allConnectors 方法从 VirtualMachineManager 获取在启动时创建的所有连接器的列表。

如果连接器安装在平台上,则在启动时创建连接器。此外,连接器由 VirtualMachineManager 自动创建,以封装平台上安装的任何 TransportService 实现。此处描述了这两种创建连接器的机制。

如果连接器安装在对 Connector 类型的定义类加载器可见的 jar 文件中,并且该 jar 文件在资源目录 META-INF/services 中包含名为 Connector 的提供程序配置文件,并且提供程序配置文件列出连接器实现的全限定类名。连接器是实现 Connector 接口的类。更恰当地说,该类实现了一种特定的连接器类型,即 AttachingConnector ListeningConnector LaunchingConnector 。提供者配置文件的格式是每行一个完全限定的类名。每个类周围的空格和制表符以及空行都将被忽略。注释字符是 '#' (0x23 ),在每一行中第一个注释字符之后的所有字符都将被忽略。该文件必须以 UTF-8 编码。

在启动时,VirtualMachineManager 尝试加载和实例化(使用无参数构造方法)提供者配置文件中列出的每个类。捕获并忽略加载或创建连接器时抛出的异常。换句话说,尽管有错误,启动过程仍会继续。

除了平台上安装的连接器之外,VirtualMachineManager 还将创建连接器来封装平台上安装的任何TransportService 实现。如果 TransportService 安装在 TransportService 类型的定义类加载器可见的 jar 文件中,并且该 jar 文件在资源目录 META-INF/services 中包含名为 TransportService 的提供程序配置文件,并且提供程序配置文件列表TransportService 实现的全限定类名。 TransportService 是 TransportService 的具体子类。提供者配置文件的格式与连接器的提供者配置文件相同,只是列出的每个类都必须是实现 TransportService 接口的类的完全限定类名。

对于平台上安装的每个 TransportService,VirtualMachineManager 都会创建相应的 AttachingConnector ListeningConnector 。创建这些连接器是为了封装一个 Transport ,而后者又封装了 TransportService。 AttachingConnector 将根据与字符串 Attach 连接的传输服务名称命名。例如,如果传输服务 name() 方法返回 telepathic,则 AttachingConnector 将被命名为 telepathicAttach。同样,ListeningConnector 将使用标记在传输服务名称上的字符串 Listen 命名。 AttachingConnector 和 ListeningConnector 的 description() 方法将委托给底层传输服务的 description() 方法。 AttachingConnector 和 ListeningConnector 都有两个 Connector Arguments 。名为 addressStringArgument 是连接器参数,用于指定要附加或监听的地址。名为 timeoutIntegerArgument 是连接器参数,用于指定附加或接受时的超时时间。超时连接器可能会被忽略,具体取决于传输服务是否支持附加超时或接受超时。

虚拟机管理器的初始化将失败,也就是说,如果虚拟机管理器无法创建任何连接器,Bootstrap.virtualMachineManager() 将引发错误。

自从:
1.3