使用简单构建工具(sbt)和IntelliJ调试Scala代码


120

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

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


6
请不要在将来提出任何疑问
hennr 2014年

Answers:


47

对于IntelliJ中的常规调试,无论是否使用sbt编译代码,都可以按常规方式使用应用程序运行/调试配置。

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

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

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


1
对我来说在通常的方式是不顺利:stackoverflow.com/questions/16337745/...
SES

您在哪里输入?-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
Jwan622 '18

@ Jwan622使用这些参数启动sbt(例如,从命令行提供,作为命令行参数提供)。然后jetty-run在sbt提示符下执行。
亚伦·诺夫斯特鲁普

所以就跑sbt -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
Jwan622 '18

3
对于大多数应该工作的用户,但这取决于系统上如何设置sbt。如其他答案所述,您也许可以运行sbt -jvm-debug 5005
亚伦·诺夫斯特鲁普

189

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

sbt -jvm-debug 5005

在幕后,这会以典型的冗长的调试方式启动JVM for SBT:

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

现在,您可以正常运行代码,例如使用sbt run命令。

配置IntelliJ以连接到正在运行的代码...

现在,您可以使用“ 远程调试”配置将IntelliJ连接到正在运行的进程。请注意,以这种形式上3场,而可怕的,是只为你复制文本出来的,而不是进入(详细上面指定调试咒语他们给的,这-jvm-debug已经为您需要照顾) -的唯一配置您可以在Settings中间的部分进行更改:

IntelliJ中的远程调试配置


1
这在Windows上不起作用-知道如何在此(糟糕的)平台上执行类似操作吗?
javadba 2014年

我相信这是Windows的启动脚本:github.com/sbt/sbt-launcher-package/blob/master/src/windows/sbt。我鼓励您弄清楚如何修改脚本以接受-jvm-debug参数,并将其作为请求请求提交-您很有可能使在同一平台上找到自己的每个人受益。
罗伯托·泰利2014年

看着它。Windows启动脚本是WAY原语与Linux。现在不能做。
javadba 2014年

1
合并拉取请求...参见下文
达伦·毕晓普

3
知道在IntelliJ中的哪里插入“ sbt -jvm 5005”会很有帮助
eddy147 '16

39

我对此也遇到了麻烦,因此冒了过于详细的风险,这是我做的:

建立

  1. 为sbt jetty-run创建运行配置

    • 转到运行>编辑配置
    • 单击[+]图标,然后选择Scala编译服务器。
    • 输入您想要的任何名称,然后单击“运行SBT Action”复选框,然后从[...]选择SBT Action码头
  2. 创建调试配置以进行远程调试

    • 转到运行>编辑配置
    • 单击[+]图标,然后选择“远程”
    • 输入您想要的任何名称并复制该行-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005(确保单击“确定”以实际创建配置)
  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. 通过选择上面创建的远程调试配置并选择“运行”>“调试”或单击“错误”图标来启动远程调试器。

16
配置菜单中没有Scala编译服务器。那我需要特别的东西吗?
Arne 2013年

似乎不需要step1,我要做的是运行sbt命令sbt -jvm-debug 5005 console,然后在intelllJ Idea中设置断点,运行调试。
Pengfei.X

@ Pengfei.X,sbt -jvm-debug 5005 console不是为我工作,而是为我工作sbt -jvm-debug 5005
Lukasz Czerwinski

8

每次都对我有用,而您唯一需要设置的就是在IntelliJ中进行远程调试。我从IntelliJ的终端使用JVM参数启动SBT:

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

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


7

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

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

创建类型为“ ScalaTest”的新“运行/调试配置”,输入主要的“测试类:”名称,然后选择“启动前:运行SBT Action'test-compile'”。就是这样,您现在可以在测试源中放置断点,然后运行此配置。


同样的,但不能很好地工作:stackoverflow.com/questions/16337745/...
SES

您知道测试类中有多个测试时如何只运行一个测试吗?你能不能请看看以下问题stackoverflow.com/questions/54977741/...
马努查达

7

这些答案或提供的链接都不对我有用,因此一旦我弄清楚了,我就想分享...

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

这主要基于此处的说明说明,并附带了一些说明。

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

背景:

  • 无论出于何种原因,使用SBT在IntelliJ中编译Scala都不像Maven项目那样集成(这使得调试非常容易)。
  • 从我的理解看来,使用SBT进行编译时,您是在一个单独的进程中进行编译,因此,您需要进行远程调试。

什么是调试?

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

什么是远程调试?

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

参考上面的链接,以下说明/修改很有用:

  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控制台中开始编译。您可以使用任何编译命令(包括连续编译命令)来执行此操作。如果进行连续重新编译,则将进行重新编译,但不会在调试器暂停代码执行时进行。

4
链接断开。
安德鲁·巴克内尔

4

我也一直在努力通过使用Intellij通过SBT构建的Spray-can / Akka / Scala应用程序在Windows上进行调试。汇集各种建议,对我来说最简单的方法是:

  1. 确保您的project / plugsin.sbt文件中有sbt.Revolver,例如

    addSbtPlugin(“ io.spray”%“ sbt-左轮手枪”%“ 0.7.1”)

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

    javaOptions:= Seq(“-Xdebug”,“ -Xrunjdwp:transport = dt_socket,server = y,suspend = y,address = 5005”)

特别是使用suspend = y选项。这将保留应用程序,直到您从Intellij连接远程调试器为止

  1. 通过“运行/编辑配置”菜单在Intellij中设置调试器配置。按下+按钮,选择“远程”选项。确保条目与上面的javaoptions相匹配,尤其是5005的端口地址。为配置指定一个名称,例如“ Spray”。

  2. 在您的SBT控制台中,使用重新启动命令。您应该在反馈输出中看到5005端口地址。

  3. 在Intellij中设置您的断点。

  4. 从Intellij中,选择“运行\调试'Spray”。这应该连接到Spray-can Web服务器。您应该能够在调试窗口中看到很多线程。

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


祝福你这个答案!像魅力一样工作。
user2770362


3

对于Windows普通用户来说,值得编辑%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

尽我所能获得相同的行为 -jvm-debug当在Bash脚本启动器中看到时,

注意 我认为%SBT_HOME%这个脚本之外并没有真正存在的方法,除非您在环境中明确创建,但是无论如何您都可以理解:D



3

文件->设置->其他设置-> SBT VM参数-Xmx512M -XX:MaxPermSize = 256M -Xdebug -Xrunjdwp:transport = dt_socket,server = y,suspend = n,address = 5005

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

现在,在SBT控制台(由intelliJ开始)中,当您执行命令“运行”时,您将看到“侦听地址为5005的传输dt_socket”

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

使用F7从下一行到下一行

我选择暂停为n。当我运行运行命令时它为y,它被卡住了


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

试试这个


0

我也遇到了同样的问题,我想分享我的解决方法。顺便说一句,我正在使用Ubuntu 14.04和IntelliJ 15。

  1. 在“设置”->“ SBT”->“粘贴在VM参数”文本框中的以下行中:

    -XX:MaxPermSize = 384M -Xdebug -Xrunjdwp:transport = dt_socket,服务器= y,暂挂= n,地址= 5005

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

    sbt -jvm调试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. 在列表框中选择DebugMyModuleEdit Configurations然后单击Debug。

    注意:您应该看到“调试视图”已打开,并且在调试控制台中,您应该能够看到“已连接到目标VM,地址:'127.0.0.1:5005',传输:'socket'”

  5. 将断点放在Testclass中的几个测试用例中。

  6. 来到运行“ sbt -jvm-debug 5005”的终端,运行如下

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

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

  7. 您可以在测试用例断点中看到调试已开始。


不适用于Ubuntu 16.04和IntelliJ 2017.3,该调试器已附加但断点被忽略。
乔纳森·诺伊菲尔德

testSuite不能在断点处停止,但是如果断点在main方法中,则可以。
升山张

0

AttachMe IntelliJ插件可能是连接调试器的更快方法,而无需摆弄端口号:

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

博客文章自述文件都有设置说明,但是我必须对其进行一些改动才能使其在我的机器上正常工作

  1. installer.sh从官方仓库下载脚本

    curl -o installer.shhttps://raw.githubusercontent.com/JetBrains/attachme/master/installer.sh
  2. 赋予它可执行权限 chmod u+x installer.sh
  3. 运行它 ./installer.sh
  4. 这应该在下面安装代理/.config/attachme/agent.jar并创建~/.attachme文件
  5. 修改~/.attachme以包含

    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. 安装相应的Attachme插件并重新启动: IntelliJ | Preferences | Plugins

  7. 创建Attachme运行配置:Run | Edit configurations... | Add new configuration | Attachme debugger registry | OK

这些一次性的恶作剧之后,我们可以通过以下方式自动附加调试器:

  1. 开始Attachme运行配置
  2. source ~/.attachme
  3. 也许从终端启动应用程序, sbt "runMain example.Hello"
  4. 调试器应自动附加并在任何断点处停止

-1

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

SBT_HOME
C:\ Program Files(x86)\ sbt \
[或安装sbt的位置]

SBT_OPTS
-Xdebug -runjdwp:transport = dt_socket,服务器= y,暂挂= n,地址= 5005

[根据RT的IntelliJ示例]

添加到路径:%SBT_HOME%\ bin;%SBT_OPTS%

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

如果此方法正常运行,则命令行最初将在“地址为5005的传输dt_socket侦听”中输出以下行。

在IntelliJ中设置断点。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.