使用 simple-build-tool (sbt)和 IntelliJ 调试 Scala 代码

使用 IntelliJ 的内置调试器调试 sbt 管理的 Scala 代码最简单的方法是什么?来自 “ RunningSbt”来自 sbt 的谷歌代码网站的文档列出了用于为项目或测试运行主类的命令,但似乎没有用于调试的命令。

后续问题: 当使用 sbt 的 Jetty-run 命令时,将 IntelliJ 的调试器附加到 Jetty 的最简单方法是什么?

110622 次浏览

对于 IntelliJ 中的普通调试,无论是否使用 sbt 编译代码,都可以以通常的方式使用 Application 运行/调试配置。

要连接到在 Jetty 中运行的应用程序,您需要创建一个 Remote debug 配置。当您这样做时,IntelliJ 将为您提供一组用于运行远程 JVM 的命令行参数——类似于

- Xdebug-Xrunjdwp: Transport = dt _ socket,server = y,susch = n,address = 5005

使用这些参数启动 sbt,然后执行 jetty-run。最后,在 IntelliJ 中启动远程调试配置。这根线可能有用。

我在这方面也遇到了一些麻烦,所以冒着过于详细的风险,我这样做了:

设置

  1. 为 sbt jetty-run 创建一个 run 配置

    • 转到 Run > Edit Configuration
    • 单击[ + ]图标并选择 Scala 编译服务器
    • 输入您想要的任何名称,然后单击“ Run SBT Action”复选框并选择 SBT Action jetty-Run from the [ ... ]
  2. 创建用于远程调试的调试配置

    • 转到 Run > Edit Configuration
    • 单击[ + ]图标并选择 Remote
    • 输入您想要的任何名称并复制行 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005(确保单击 OK 以实际创建配置)
  3. 设置 sbt 插件来运行上面的 vm 选项

    • 转到文件 > 设置 > SBT
    • 将行 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005粘贴到 VM 参数框中,在已经存在的参数之后

调试中

  1. 根据需要设置断点
  2. 通过选择上面创建的 sbt jetty-Run 配置并选择 Run > Run 或单击绿色箭头来启动 jetty web 服务器
  3. 通过选择上面创建的远程调试配置并选择 Run > Debug 或单击 bug 图标来启动远程调试器

我在这里添加了另一个答案,因为我在查找相关问题时发现了这个问题: 使用断点调试测试类。

我使用的是 ScalaTest,通常使用 sbt 的“仅测试”命令运行一个套件。现在,当我想使用交互式调试器时,我可以执行以下操作:

创建一个类型为‘ ScalaTest’的新 Run/Debug Configuration,输入主要的“ Test Class:”名称,然后选择“ Before unch: Run SBT Action‘ Test-coding’”。就是这样,您现在可以在测试源代码中放置断点,并运行此配置。

在 Mac、 Linux 和 窗户的官方 SBT 软件包中有一个非常方便的 -jvm-debug标志。您可以使用该标志来指定调试端口:

sbt -jvm-debug 5005

之下,这将使用典型的冗长调试咒语启动 SBT 的 JVM:

-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005

现在可以像正常情况一样运行代码,例如使用 sbt run命令。

将 IntelliJ 配置为连接到正在运行的代码..。

现在使用 < em > 远程调试配置 将 IntelliJ 连接到正在运行的进程。请注意,这个表单的上面3个字段,虽然可怕,只是为了让你复制文本 出去的,而不是进入(他们给出详细的调试咒语上面指定的 -jvm-debug已经照顾你)-唯一的配置,你可以改变的是在 Settings部分的一半下来:

Remote Debug configuration in IntelliJ

这些答案和提供的链接都不适合我,所以一旦我明白了这一点,我想我应该分享..。

包括我刚开始的时候没有的背景知识。

这主要是基于指示 给你只是附加的解释,带我通过它。

我的环境: Scala 2.10.2、 SBT 0.13和 IntelliJ 13.1

背景:

  • 不管出于什么原因,在 IntelliJ 中使用 SBT 编译 Scala 并不像 Maven 项目那样集成(这样可以很容易地进行调试)。
  • 根据我的理解,在使用 SBT 进行编译时,需要在单独的进程中进行编译,因此需要进行远程调试。

什么是调试?

  • 调试是一种可以运行 JVM 或应用程序的模式,它允许您控制代码执行的流程。
  • 然后,你使用的调试工具可以向调试引擎发出命令,告诉它“执行下一行代码,然后再次暂停”或“继续执行”或“获取存储在内存中的变量的值”。

什么是远程调试?

  • 远程调试通过网络连接(套接字)进行调试。
  • 此网络连接允许您从远程计算机向调试引擎发出命令。
  • 这对于调试在远程服务器上运行的代码非常有用,但是
  • 对于在 SBT 下运行的 Scala 代码和通过 Web 服务器(如 Jetty 或 Tomcat)启动的情况,它也非常有用,这些服务器与 IntelliJ 环境是分开的。

参考以上连结,以下解释/修订是有用的:

  1. 安装 IntelliJ,使用“启用调试”JVM 设置启动 SBT,包括设置网络套接字时使用的端口。(未更改)将命名的 VM 参数添加到 IntelliJ 设置中。
  2. 确保这里的端口号与步骤1中的 JVM 设置相匹配。
  3. 当您启动 SBT 时,您需要从 SBT Console 插件(这是您在步骤1中配置的)执行。如果在 IntelliJ 之外运行 SBT (在命令行) ,则需要使用步骤1中的相同 VM 参数启动 SBT (我没有这样做; 因此没有指令)。完成这一步之后,SBT 现在正在运行(但是您的代码还没有运行) ,JVM 已经为远程调试设置好了。
  4. 这将启动 IntelliJ 调试工具,它将连接到您在步骤3中启动的 JVM。
  5. 最后,在 SBT 控制台中开始编译。您可以使用任何编译命令(包括连续编译命令)来完成此操作。如果连续重新编译,则重新编译将发生,但不会在调试器暂停代码执行时发生。

我也一直在努力调试通过 SBT 和 Intellij 构建的 Spray-can/阿卡/Scala 应用程序。综合各种建议,对我来说最简单的方法是:

  1. 确保在项目/plugsin.sbt 文件中有 sbt. Revolver。

    AddSbtPlugin (“ io.jet”% “ sbt-evolver”% “0.7.1”)

  2. 在 build.sbt 文件中设置 javaoptions:

    JavaOptions: = Seq (“-Xdebug”,“-Xrunjdwp: Transport = dt _ socket,server = y,susch = y,address = 5005”)

特别是使用中止 = y 选项,这将保持应用程序,直到你从 Intellij 连接到一个远程调试器

  1. 通过“运行/编辑配置”菜单在 Intellij 设置调试器配置。按 + 按钮,选择“远程”选项。确保条目与上面的 javaoptions 匹配,特别是端口地址5005。给配置一个类似“ Spray”的名称。

  2. 从 SBT 控制台使用 re-start 命令。

  3. 在 Intellij 中设置断点。

  4. 从 Intellij,选择运行调试“喷雾”。这应该连接到喷罐网络服务器。您应该能够在调试窗口中看到许多线程。

  5. 请注意,Spray 中的一些 Get 指令似乎在启动时执行,但在调用网站时不会重复执行。

不管怎样,编辑 %SBT_HOME%\bin\sbt.bat并找到下面几行代码:

:run


"%_JAVACMD%" %_JAVA_OPTS% %SBT_OPTS% -cp "%SBT_HOME%sbt-launch.jar" xsbt.boot.Boot %*
if ERRORLEVEL 1 goto error
goto end

然后用以下代码替换它们:

FOR %%a IN (%*) DO (
if "%%a" == "-jvm-debug" (
set JVM_DEBUG=true
set /a JVM_DEBUG_PORT=5005 2>nul >nul
) else if "!JVM_DEBUG!" == "true" (
set /a JVM_DEBUG_PORT=%%a 2>nul >nul
if not "%%a" == "!JVM_DEBUG_PORT!" (
set SBT_ARGS=!SBT_ARGS! %%a
)
) else (
set SBT_ARGS=!SBT_ARGS! %%a
)
)


if defined JVM_DEBUG_PORT (
set _JAVA_OPTS=!_JAVA_OPTS! -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=!JVM_DEBUG_PORT!
)


call :run %SBT_ARGS%


if ERRORLEVEL 1 goto error
goto end


:run
"%_JAVACMD%" %_JAVA_OPTS% %SBT_OPTS% -cp "%SBT_HOME%sbt-launch.jar" xsbt.boot.Boot %*
goto :eof

当在 Bash 脚本启动程序中看到 -jvm-debug的相同行为时,我所能做的最好的事情

注意。我不认为 %SBT_HOME%实际上存在于这个脚本之外,除非您在自己的环境中明确地创建了它,但是不管怎么说,您得到了这样一个结论: D

文件-> 设置-> 其他设置-> SBT VM 参数 - Xmx512M-XX: MaxPermSize = 256M-Xdebug-Xrunjdwp: Transport = dt _ socket,server = y,susch = n,address = 5005

运行-> 编辑配置 按 + ,然后选择远程 按申请

现在在 SBT 控制台(在内部由 intelliJ 启动) ,当您执行命令‘ run’时,您将看到“ ListingforTransport dt _ socket at address: 5005”

现在按 Run-> Debug。您将看到下面的调试菜单被激活。它有两个标签 Debugger 和 Console。

使用 F7从下一行到下一行

当我运行 run 命令时,它被卡住了

这个方法对我来说每次都管用,您唯一需要设置的是在 IntelliJ 中进行远程调试; 我从 IntelliJ 中的终端用 JVM 参数启动 SBT:

sbt -J-Xdebug -J-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005

之后,我可以在 localhost: 5005上开始远程调试

我也有同样的问题,我喜欢分享我是如何解决的。顺便说一下,我正在使用 Ubuntu 14.04和 IntelliJ 15。

  1. 在设定中-> SBT-> 粘贴到 VM 参数文本框的下面一行:

    - XX: MaxPermSize = 384M-Xdebug-Xrunjdwp: Transport = dt _ socket,server = y,susch = n,address = 5005

  2. 在 IntelliJ 中打开 Termilal 并运行:

    Sbt-jvm-debug 5005

    注意: 您应该在终端中看到这一行: “监听地址: 5005的 dt _ socket 的传输”

  3. 编辑配置-> 点击 +-> 选择“远程”

    I. Give some name example: DebugMyModule
    
    
    II. All needed configurations will be set automatically, But you just verify. In Command line arguments should look like this "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005".
    
    
    III. In 'Search Sources in Module's Classpath' text box specify your module in which module your test cases are there.
    
    
    IV. put 127.0.0.1 host instead of 'localhost'. 'localhost' not working for me.
    
  4. Select DebugMyModule in Edit Configurations list box and click Debug.

    Note: You should see Debug View opened and in Debug Console You should able to see "Connected to the target VM, address: '127.0.0.1:5005', transport: 'socket'"

  5. Put breakpoints in few test cases in your Testclass.

  6. Come to Terminal where you run "sbt -jvm-debug 5005" and run like below

    project <your-module-name>
    it:testOnly package.TestSpec
    

    例如: com.myproject.module. AddServiceTest [ Spec ]

  7. 可以在测试用例断点中看到已启动的调试。

export SBT_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5009

试试这个

根据 Roberto Tyley 上面的回答,在 Windows 中,我们还需要在安装 sbt 之后设置以下环境变量:

SBT _ Home
C: Program Files (x86) sbt
[或安装 sbt 的任何地方]

SBT _ OPTS
- Xdebug-runjdwp: Transport = dt _ socket,server = y,susch = n,address = 5005

[根据 RT 的 IntelliJ 示例]

添加到路径:% SBT _ HOME% bin;% SBT _ OPTS%

然后在项目文件夹中的命令行中运行以下命令 “ sbt run-jvm-debug 5005”。

如果工作正常,命令行最初将输出一行 re “正在监听地址: 5005的 dt _ socket 传输”。

在 IntelliJ 中设置断点。

在浏览器中打开网站,触发调试器断点,例如“ http://localhost:9000/”。

AttachMe IntelliJ 插件可能会更快地附加调试器,而不必修改端口号:

AttachMe 将附加 IntelliJ 调试器 自然而然地,即使您 从终端(或任何其他方式)启动应用程序 手动触发 Attach to process动作。

Blog post 自述都有设置指令,但是我不得不稍微修改一下才能让它在我的机器上正常工作

  1. 从官方回购下载 installer.sh脚本

    curl -o installer.shhttps://raw.githubusercontent.com/JetBrains/attachme/master/installer.sh
    
  2. Give it executable permissions chmod u+x installer.sh
  3. Run it with ./installer.sh
  4. This should install the agent under /.config/attachme/agent.jar and create ~/.attachme file
  5. Modify ~/.attachme to contain

    AM_JDWP_ARGS="transport=dt_socket,server=y,suspend=y,address=127.0.0.1:0"
    echo Using JDWP arguments ${AM_JDWP_ARGS}
    export JAVA_TOOL_OPTIONS="- javaagent:/Users/mario_galic/.config/attachme/agent.jar -agentlib:jdwp=${AM_JDWP_ARGS}"
    echo "AttachMe configured successfully"
    
  6. Install corresponding Attachme plugin and restart: IntelliJ | Preferences | Plugins

  7. Create Attachme run configuration: Run | Edit configurations... | Add new configuration | Attachme debugger registry | OK

After these one-off shenanigans, we can attach a debugger automatically by

  1. Start Attachme run configuration
  2. source ~/.attachme
  3. Start application from terminal, perhaps, sbt "runMain example.Hello"
  4. The debugger should automatically attach and stop at any breakpoint

关于相对较新版本的 Intellij (2020.1.4) ,请一步一步地给出一分钱:

  • 配置 Intellij

    • “编辑配置”
      enter image description here
    • 添加“远程”
      这个新版本的 Intellij 不允许你编辑“命令行参数”中的字符串,你只能编辑上面的“主机”和“端口”,我把它保留为默认值,我只把下面的“模块路径”改为“根”(不确定是否有必要) enter image description here
  • 远程调试

    • 设置断点
    • 命令行中执行 sbt命令,例如 sbt -jvm-debug 5005 test
    • 立即回到 Intellij,点击“ Debug”,它应该会显示类似于“ Connected to xxx”的内容,然后等待到断点处暂停
      enter image description here