5

I have an sbt project which I ran "gen-idea" to setup to work with Intellij 12.4. In one project is my main code an the other project has my macro code. When trying debug my macro via a test file by following http://docs.scala-lang.org/overviews/macros/overview.html but throws:

error: scala.reflect.internal.MissingRequirementError: object scala.runtime in compiler mirror not found.
at scala.reflect.internal.MissingRequirementError$.signal(MissingRequirementError.scala:16)
at scala.reflect.internal.MissingRequirementError$.notFound(MissingRequirementError.scala:17)
at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:48)
at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:40)
at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:61)
at scala.reflect.internal.Mirrors$RootsBase.getPackage(Mirrors.scala:172)
at scala.reflect.internal.Mirrors$RootsBase.getRequiredPackage(Mirrors.scala:175)
at scala.reflect.internal.Definitions$DefinitionsClass.RuntimePackage$lzycompute(Definitions.scala:181)
at scala.reflect.internal.Definitions$DefinitionsClass.RuntimePackage(Definitions.scala:181)
at scala.reflect.internal.Definitions$DefinitionsClass.RuntimePackageClass$lzycompute(Definitions.scala:182)
at scala.reflect.internal.Definitions$DefinitionsClass.RuntimePackageClass(Definitions.scala:182)
at scala.reflect.internal.Definitions$DefinitionsClass.AnnotationDefaultAttr$lzycompute(Definitions.scala:1015)
at scala.reflect.internal.Definitions$DefinitionsClass.AnnotationDefaultAttr(Definitions.scala:1014)
at scala.reflect.internal.Definitions$DefinitionsClass.syntheticCoreClasses$lzycompute(Definitions.scala:1144)
at scala.reflect.internal.Definitions$DefinitionsClass.syntheticCoreClasses(Definitions.scala:1143)
at scala.reflect.internal.Definitions$DefinitionsClass.symbolsNotPresentInBytecode$lzycompute(Definitions.scala:1187)
at scala.reflect.internal.Definitions$DefinitionsClass.symbolsNotPresentInBytecode(Definitions.scala:1187)
at scala.reflect.internal.Definitions$DefinitionsClass.init(Definitions.scala:1252)
at scala.tools.nsc.Global$Run.<init>(Global.scala:1290)
at scala.tools.nsc.Driver.doCompile(Driver.scala:32)
at scala.tools.nsc.Main$.doCompile(Main.scala:79)
at scala.tools.nsc.Driver.process(Driver.scala:54)
at scala.tools.nsc.Driver.main(Driver.scala:67)
at scala.tools.nsc.Main.main(Main.scala)

I have checked to ensure that in my class path that ALL jars from SCALA_HOME/lib/ are included and they are. Btw this is with Scala v2.10.2

cideas
  • 63
  • 1
  • 5

3 Answers3

9

I just want to note for future readers that it's also possible to start your sbt in debug mode and then connect the idea debugger remotely.

  • start sbt with: sbt -jvm-debug 5005
  • create a "Remote" "Run/Debug Config" in idea (defaults to port 5005)

Run the remote-debug config in idea. That will connect it to your running sbt. Then you can set breakpoints in your macro code and when running compile in sbt, idea should stop at the breakpoint.

note: to re-run compile after a successful compile you need either to clean or change some code

trudolf
  • 1,809
  • 16
  • 11
  • 1
    Starting with the 2018 Intellij, there is a handy little "attach debugger" button on the sbt console. Run your command and it breaks as expected. – Grant BlahaErath Mar 30 '19 at 03:04
4

As we figured out at #scala, the documentation was missing the fact that one needs to provide the -Dscala.usejavacp=true argument to the JVM command that invokes scalac. After that everything worked fine, and I updated the docs: http://docs.scala-lang.org/overviews/macros/overview.html#debugging_macros.

Eugene Burmako
  • 13,028
  • 1
  • 46
  • 59
3

Step-by-step instructions about setting up IntelliJ to debug Scala macros:

  1. First, you need to have a unit test that exercises your macro. Suppose this unit test is MacroSpec.scala in project Macro, and it contains a test class MacroSpec. Suppose your project has package name com.example.project.

  2. "Run/Edit configurations..." - you need to add a new configuration under "Applications". Call this configuration "Macro debugger".

  3. Setup various options on the configuration.

    • Main class: scala.tools.nsc.Main - this is the compiler's main class. (You will be debugging the compiler pass that runs the macro.)
    • VM options: -Dscala.usejavacp=true
    • Program arguments: this is all in one very long line, -cp com.example.project.MacroSpec /home/YourUserName/path/to/your/project/src/test/scala/com/example/project/MacroSpec.scala You will need to edit this according to your actual path and package name.
    • Working directory: /home/YourUserName/path/to/your-project. You will need to edit this.
    • Environment variables: you can leave this blank
    • Use classpath of module: macro - this must be the module in your IntelliJ project that contains the macro code and its dependencies.
    • Before launch: "Make, no error check". This helps if there are errors in your test code - the macro will be run anyway. (In some cases, you may want to introduce errors deliberately and debug your macro on wrong code.)
    • Press OK. Save this configuration.
  4. In build.sbt or Build.scala of your project, make sure that the macro module has the following dependency: "org.scala-lang" % "scala-compiler" % scalaVersion.value % "test". Here you might want to check that you have scalaVersion declared. The "test" option is there to avoid bundling the scala compiler JAR into your final application JAR.

  5. Go to your macro code and set a breakpoint. Then run the "Macro debugger". You should be stopped at the breakpoint.

winitzki
  • 3,179
  • 24
  • 32
  • I followed all of the steps you mentioned and I'm getting an error saying it cannot find my main class. – Ryan Stull Jan 10 '19 at 22:12
  • I think this stopped working with most recent versions of IntelliJ. Use the previous answer with `sbt -jvm-debug 5005` perhaps? – winitzki Jan 14 '19 at 07:34