5
votes

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

3
Could you please elaborate on how you run the debugging session? Do you use Intellij's debug runner or a remote debugger? - Eugene Burmako

3 Answers

4
votes

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.

7
votes

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

3
votes

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.