Debug Scala compiler plugin in IntelliJ IDEA - scala

I would like to write my compiler plugin for scalac, but I get a problem in early state in development because I cannot run and debug my code from IntelliJ IDEA.
I use these tutorials for implementing a dummy plugin:
Scalac plugin template
An old post from scala-lang.org
My goal is to run my plugin somehow in debug mode in IDEA to encounter breakpoints.
Update:
The answer below helped me a lot but actually, I added arguments for debugging for JAVA_OPTS environment variable with suspending until remote debugger connection option. Then I started scalac and run remote debugger described below.

To debug a java process in IntelliJ IDEA you need to create a Remote run configuration first.
Specify an available port number. If you select Listen debugger mode your java process will be suspended on the start until you connect to it with the debugger.
Run your process with additional command line arguments and start this remote configuration in the debug mode.
If you run scala compiler from IDEA, these command line arguments should be added to Scala Compile Server:

Related

Setting debugging traces when running tests on Intellij

Does interactive debugging work when running tests inside Intellij ? I'm setting traces before running tests, but tests are run and I am never given control to debug.
When running tests I get Error running PipelinesTest: Invalid arguments : Already listening [timeout, port, localAddress]. But then tests are run and I'm not given control.
The problem was that apparently the debugger doesn't work when having "Use sbt" checkbox activated in the intellij config type.

Intellij Play and Scala breakpoint issues

I am having some problems with the IntelliJ IDE where it does not stop at breakpoints.
I am running an SBT application with Play 2 framework.
It doesn't matter if I am in an async block or not, the breakpoint doesn't show a "v" inside the red circle and doesn't stop at that breakpoint.
The code reaches that position because I am using a simple print command that I see in the logs.
I tired with run configuration of Play2.
I also tried running the SBT from console and connecting to it with remote debugging.
None of them worked
just to make things clear i tried restarting intellij and the computer (OSX operating system)
This is a real problem. Any ideas?
Try execute "sbt compile" and then run your project on debug mode.

Scala Console in IntelliJIDEA neither acccepts input nor prints output, comand works from temrinal

I have a "Scala/Simple module with attached Scala SDK" type project in IntelliJIDEA with which I was easily able to build and setup a couple of application configurations. A Scala workspace also works fine, but when I try to create and run a Scala Console configuration the terminal comes up, the Scala Repl appears to run fine, in that it gives me the Welcome to Scala message and prints an initial "scala>". However, although autocompletion works, the Repl otherwise appears dead to the world: nothing is returned or printed, and when I restarted and entered a one-liner to write some text to a file to test if it was just an ouptut-capture issue, that file did not appear.
I am running IntelliJIDEA 15.0.2 / idea-IU-143.1184.17 on Debian.
When I copy the command being run by IntelliJIDEA and run from a console, it works fine; command copied from IntelliJIDEA Scala Console follows:
/usr/lib/jvm/java-7-openjdk-amd64/bin/java -Djline.terminal=NONE -Didea.launcher.port=7543 -Didea.launcher.bin.path=/usr/local/idea-IU-143.1184.17/bin -Dfile.encoding=UTF-8 -classpath /home/pacs/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.11.7.jar:/home/pacs/.ivy2/cache/org.scala-lang/scala-compiler/jars/scala-compiler-2.11.7.jar:/home/pacs/.ivy2/cache/org.scala-lang/scala-reflect/jars/scala-reflect-2.11.7.jar:/home/pacs/.IntelliJIdea15/config/plugins/Scala/lib/scala-plugin-runners.jar:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/charsets.jar:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/compilefontconfig.jar:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/ext/dnsns.jar:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/ext/icedtea-sound.jar:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/ext/java-atk-wrapper.jar:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/ext/localedata.jar:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/ext/sunpkcs11.jar:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/ext/zipfs.jar:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/javazic.jar:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/jce.jar:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/jsse.jar:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/management-agent.jar:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/resources.jar:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rhino.jar:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar:/home/pacs/IdeaProjects/scap/out/production/scap:/usr/local/idea-IU-143.1184.17/lib/idea_rt.jar com.intellij.rt.execution.application.AppMain org.jetbrains.plugins.scala.compiler.rt.ConsoleRunner -usejavacp
I'm rather new to the JetBrains family of IDEs so I may be missing something obvious; does anyone have any ideas?
EDIT: I tried this on IntelliJIDEA 15.0.0 on OS X with scala 2.10.6 and JDK 1.8 with the same result so I am inclined to believe this is not a JDK, Scala, or OS-specific problem.
OK, finally figured this out: it's not a normal console where you press enter; instead you use whatever keymap goes to Plug-ins/Scala/Execute Console Statement-- probably Ctrl+Enter or ⌘+Enter.
Other people seem to have been stumped also:
Scala console won't work, IntelliJ
The IntelliJIDEA console is very nice once you know this; with autocompletion, auto-formatting, and no issues with multiline code. If I had one request though, it would be to ask the JetBrains team to please add something to the Scala Console welcome message which indicates that this is not a normal console and maybe a quick hint on how to use it.

No Java console output in Eclipse; works with PyDev

I have both a Java and a PyDev project in one workspace. When I run the PyDev project (either the main script with Run > Run As > Python Run or its associated unit test with Python unit-test), the console output looks fine. However, when I switch to the Java project, open the main class, make sure the cursor focus is in the main class, and run it with Run > Run as > [my run config], no output shows up in the console, stdout or stderr. I've tried with Run/Debug > Console > Fixed width console checked and unchecked, similarly for Limit console output. "Allocate console" is check in [my run config].
I have tried redirecting output to a file in my run configuration, but the log file is empty after a run; thus, I suspect stdout/stderr are being trapped somewhere. I suspect that it is PyDev causing the issue because when I run the Java project, this exception reliably shows up about 6 times in the error log:
Launch shortcut 'org.python.pydev.debug.ui.launchShortcut.python.unittest' enablement expression caused exception. Shortcut was removed.
stacktrace:
org.eclipse.core.runtime.CoreException: No property tester contributes a property org.python.pydev.debug.ui.python_type to type class org.eclipse.ui.part.FileEditorInput
at org.eclipse.core.internal.expressions.TypeExtensionManager.getProperty(TypeExtensionManager.java:123)
at org.eclipse.core.internal.expressions.TestExpression.evaluate(TestExpression.java:96)
at org.eclipse.core.internal.expressions.CompositeExpression.evaluateOr(CompositeExpression.java:68)
at org.eclipse.core.internal.expressions.OrExpression.evaluate(OrExpression.java:21)
at org.eclipse.core.internal.expressions.CompositeExpression.evaluateAnd(CompositeExpression.java:53)
at org.eclipse.core.internal.expressions.AndExpression.evaluate(AndExpression.java:29)
(... and so on)
Additionally, printing from a Java program in a different workspace that only has Java projects works fine.
I tried uninstalling PyDev and restarting Eclipse, but I'm still having the same issue. I still have those errors after reinstalling PyDev, too.
Has anyone run into this issue before, or know of a way to fix it?
Well, I feel like an idiot; turns out, I had redirected stdout/err to a log file that I had long since forgotten about, and stuck somewhere difficult to find.
I ran into the same problem so I did some research. Seems like there was an old issue (2006-2008), but it was resolved by adding an option to the launch configurations to allocate a console. This is available from the Run -> Debug Configurations menu option, Common tab. Perhaps this is simply unchecked after the PyDev install?
If this is a new bug, there were two possible workarounds suggested:
Set up debug launch configuration that uses remote debugging instead of local debugging.
Use a buffered writer to System.out.
Here are the threads for reference:
Eclipse bug - https://bugs.eclipse.org/bugs/show_bug.cgi?id=122429
Workaround thread - java.io.Console support in Eclipse IDE

Debugging Scala code with simple-build-tool (sbt) and IntelliJ

What's the easiest way to debug Scala code managed by sbt using IntelliJ's built-in debugger? The documentation from "RunningSbt" from sbt's google code site lists commands for running the main class for a project or the tests, but there seem to be no commands for debugging.
Follow-up question: what's the easiest way to attach IntelliJ's debugger to Jetty when using sbt's jetty-run command?
There's a very convenient -jvm-debug flag in the official SBT packages for Mac, Linux & Windows. You can use the flag to specify the debug port:
sbt -jvm-debug 5005
Under the covers, this starts the JVM for SBT with the typical verbose debugging incantation:
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
You now can run your code as normal, for example with the sbt run command.
Configuring IntelliJ to connect to the running code...
Now you connect IntelliJ to your running process using a Remote Debug configuration. Note that the upper 3 fields in this form, while scary, are just for you to copy text out of, rather than into (they're giving the verbose debugging incantation specified above, which -jvm-debug already takes care of for you) - the only configuration you can change is in theSettings section halfway down:
For ordinary debugging in IntelliJ, you can use an Application run/debug configuration in the usual way, regardless of whether you're using sbt to compile your code.
To connect to your application running in Jetty, you'll need to create a Remote debug configuration. When you do so, IntelliJ will give you a set of command line arguments for running the remote JVM -- something like
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
Launch sbt with these arguments and then execute jetty-run. Finally, launch your remote debug configuration in IntelliJ. This thread might be useful.
I had some trouble with this too, so at the risk of being overly detailed, here's what I did:
SETUP
Create a run configuration for sbt jetty-run
Go to Run > Edit Configurations
Click the [+] icon and choose Scala Compilation Server
Enter whatever name you want, and click the "Run SBT Action" checkbox and select the SBT Action jetty-run from the [...]
Create a debug configuration for remote debugging
Go to Run > Edit Configurations
Click the [+] icon and choose Remote
Enter whatever name you want and copy the line -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 (make sure to click OK to actually create the configuration)
Set up sbt plugin to run the vm options above
Go to File > Settings > SBT
Paste the line -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 in the VM parameters box, after the ones that are already there
DEBUGGING
Set breakpoints as desired
Start the jetty web server by choosing the sbt jetty-run configuration you created above and choosing Run > Run or by clicking the green arrow
Start the remote debugger by choosing the remote debugging configuration you created above and choosing Run > Debug or by clicking the bug icon
This one works for me every time, and the only thing you need to set up is remote debugging in IntelliJ; I start up SBT with JVM parameters from the terminal in IntelliJ:
sbt -J-Xdebug -J-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
After that I can start remote debugging on localhost:5005
None of these answers or provided links worked for me, so once I figured this out, I figured I'd share...
including the background understanding I didn't have when I started...
This is based mostly on the instructions here just with additional explanation that carried me through it.
My Environment:
Scala 2.10.2, SBT 0.13, and IntelliJ 13.1
Background:
For whatever reason, using SBT to compile Scala in IntelliJ isn't integrated the way Maven projects are (which allow debugging really easily).
It appears from my understanding that when compiling with SBT, you're compiling in a separate process, therefore, you need to be remotely debugging.
What is Debugging?
Debugging is a mode you can run your JVM or app in that allows you to control the flow of code execution.
The Debugging Tool you use can then issue commands to the Debugging Engine that tells it "execute the next line of code then pause again" or "continue executing" or "get the value of the variable stored here in memory".
What is Remote Debugging?
Remote Debugging is debugging over a network connection (socket).
This network connection allows you to issue the commands to the Debug Engine from a remote machine.
This is useful for when you want to debug code that's running on a remote server, BUT
It's also useful for situations like Scala code running under SBT and launching via a web server, such as Jetty or Tomcat, separate from your IntelliJ environment.
Referencing the link above, the following explanations/modifications are useful:
Setup IntelliJ to launch SBT with the "enable debugging" JVM settings, including the port to use when setting up the network socket. (unchanged) add the named VM parameters to your IntelliJ settings.
Ensure your port number here matches your JVM settings from Step 1.
When you launch SBT, you need to do it from the SBT Console plugin (which is what you configured in Step 1). If you're running SBT outside of IntelliJ (at the commandline), you'll need to launch SBT with the same VM parameters from Step 1 (I didn't do this; so no instructions). After this step, SBT is now running (but your code is not yet) and the JVM is setup for Remote Debugging.
This starts the IntelliJ Debugging Tool, which connects to the JVM you started in Step 3.
Finally, you start the compilation in the SBT Console. You can do this with any compilation command, including a continuous compilation command. If continuous re-compile, the recompile will happen, but not while code execution is paused by the debugger.
I am adding another answer here, because I found this question when looking up a related problem: Debugging test classes using breakpoints.
I am using ScalaTest, and I typically run a suite using sbt's 'test-only' command. Now when I want to use the interactive debugger, I can do the following:
Create a new Run/Debug Configuration of type 'ScalaTest', put the main "Test Class:" name, and choose "Before launch: Run SBT Action 'test-compile'". That's it, you can place breakpoints now in the test sources, and run this configuration.
I've been struggling with debugging too on Windows with a Spray-can / Akka / Scala app built via SBT, using Intellij. Piecing together various suggestions, the simplest approach for me was:
Make sure you have sbt.Revolver in your project/plugsin.sbt file e.g.
addSbtPlugin("io.spray" % "sbt-revolver" % "0.7.1")
Set javaoptions in you build.sbt file:
javaOptions := Seq("-Xdebug", "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005")
In particular use the suspend=y option. This will hold the app until you connect a remote debugger from Intellij
Set up a debugger configuration in Intellij via Run / Edit Configurations menu. Press the + button, select the "Remote" option. Make sure the entries match the javaoptions above, in particular the port address of 5005. Give the config a name like 'Spray'.
From your SBT console use the re-start command. You should see the 5005 port address in the feedback output.
In Intellij set your breakpoints.
From Intellij, select the Run \ Debug 'Spray'. This should connect to the spray-can web server. You should be able to see a lot of threads in the debug window.
Beware that some of the Get directives in Spray seem to get executed on start up but not repeatedly on calling the website.
File->Settings->Other Settings->SBT
VM parameters
-Xmx512M -XX:MaxPermSize=256M -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
Run->Edit Configurations
Press + and then select remote
Press Apply
Now in the SBT console (Started inside by intelliJ) when you execute the command 'run' You will see "Listening for transport dt_socket at address: 5005"
Now press Run->Debug. You will see the debug menus below activated. It has two tabs Debugger and Console.
Use F7 to from next line to next
I chose suspend to be n. With it being y when I ran the run command it was stuck
export SBT_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5009
try this
For what it's worth Windows folk, edit %SBT_HOME%\bin\sbt.bat and locate the following lines of code:
:run
"%_JAVACMD%" %_JAVA_OPTS% %SBT_OPTS% -cp "%SBT_HOME%sbt-launch.jar" xsbt.boot.Boot %*
if ERRORLEVEL 1 goto error
goto end
then replace them with this code:
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
Best I can do to get same behaviour for -jvm-debug when seen in the Bash script launcher
NB. I don't think %SBT_HOME% actually exists outside this script, unless you created explicitly in you environment, but anyway you get the point :D
AttachMe IntelliJ plugin is potentially faster way off attaching the debugger without having to fiddle with port numbers:
AttachMe will attach the IntelliJ debugger automatically even if you
start your app from terminal (or any other way). You don't need to
trigger Attach to process action manually.
Blog post and readme have setup instructions, however I had to alter them a bit to get it working on my machine
Download installer.sh script from official repo
curl -o installer.shhttps://raw.githubusercontent.com/JetBrains/attachme/master/installer.sh
Give it executable permissions chmod u+x installer.sh
Run it with ./installer.sh
This should install the agent under /.config/attachme/agent.jar and create ~/.attachme file
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"
Install corresponding Attachme plugin and restart: IntelliJ | Preferences | Plugins
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
Start Attachme run configuration
source ~/.attachme
Start application from terminal, perhaps, sbt "runMain example.Hello"
The debugger should automatically attach and stop at any breakpoint
I also got the same problem, I like to share how I resolved. By the way I am using Ubuntu 14.04 and IntelliJ 15.
In Setting -> SBT ->
Pasted below line in VM Parameters text box:
-XX:MaxPermSize=384M -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
Opened Termilal in IntelliJ and run:
sbt -jvm-debug 5005
Note: you should see this line in terminal: "Listening for transport dt_socket at address: 5005"
Edit Configurations -> Click + -> Select 'Remote'
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.
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'"
Put breakpoints in few test cases in your Testclass.
Come to Terminal where you run "sbt -jvm-debug 5005" and run like below
project <your-module-name>
it:testOnly package.TestSpec
For example: com.myproject.module.AddServiceTest[Spec]
You can see debug started in your test case breakpoint.
Give a cent step by step regarding a relatively new version of Intellij (2020.1.4):
Configure Intellij
"Edit Configurations"
Add "Remote"
This new version of Intellij does not allow you to edit the string in the "Command line arguements", you can only edit the "Host" and "Port" above, which I leave it default; I only change the "module path" below to "root" (not sure if it's necessary)
Remote debug
Set your break point
Execute sbt command in command line, e.g. sbt -jvm-debug 5005 test
Immediately go back to Intellij and click on "Debug", it should show something like "Connected to xxx", then wait till it suspends at your break point
As per Roberto Tyley's answer above, but in Windows we also need to set the following environment variables after installing sbt:
SBT_HOME
C:\Program Files (x86)\sbt\
[or wherever sbt is installed]
SBT_OPTS
-Xdebug -runjdwp:transport=dt_socket,server=y,suspend=n,address=5005
[per RT's IntelliJ example]
Add to path: %SBT_HOME%\bin;%SBT_OPTS%
Then run the following in the command line within the project folder
"sbt run -jvm -debug 5005".
If this is working properly, the command line will initially output a line re
"Listening for transport dt_socket at address: 5005".
Set breakpoint in IntelliJ.
Open website in browser to trigger the debugger breakpoint e.g. "http://localhost:9000/".