Launch jvm in debug mode with external tool under debug configuration

I'm trying to debug my unit tests using IntelliJ remote debugging feature.

The project I'm maintaining is based on an old version of play framework (2.4), and I'm currently trying to configure IntelliJ to launch the unit tests in debug mode. Here's what I managed to do so far:

- I configure my build.sbt to launch the tests jvm in debug mode by adding the following: 

javaOptions in Test += "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9990"

- I run the tests using "activator test"

- as soon I see "Listening for transport dt_socket at address: 9990" I run my IntelliJ debug configuration configured to hook up to localhost:9990

This works perfectly and allows me to debug my code as expected, but the workflow isn't the best, so I've been trying to tweak my remote debug configuration to achieve the above on a single click. I basically add a "Run External Tool" to my debug configuration under "Before Launch: activate tool window" and make it run "activator test" under the proper working directory which launches the tests properly when I run the configuration but doesn't hook up the debugger.

The problem is I can't think of a way to instruct my IntelliJ debug configuration to hook up with the tests jvm when it gets launched by activator.

Note that activator doesn't launch the jvm on which the tests run immediately, it takes it a few seconds to load other stuff before doing so.

________________________________________________

Why not use the debug test menu item to launch tests? because for some reason in debug mode the vm loads the original app config file instead of a test config I specify in my build.sbt as follows

javaOptions in Test += "-Dconfig.file=conf/test-application.conf"

This behavior causes my tests to fail due to configuration conflicts. Note that this happens only in debug mode, as opposed to "run" mode where my test config file is loaded properly allowing my tests to run as expected.

________________________________________________

Any hints are appreciated.

 

7 comments

Try to use "Listen" Debugger Mode in remote run configuration. Don't forget to update command line argument in Test.

In this case order of launch is not important, both processes will wait each other.

0

Thanks a lot!

I tried the "Listen" Debugger Mode, and updated my test command line argument as follows:

-agentlib:jdwp=transport=dt_socket,server=n,address=alayouni-HP-Z420-Workstation:9990,suspend=y

as suggested by IntelliJ (I only omitted "onthrow=<FQ exception class name>,onuncaught=<y/n>" since after a quick search they appear to be optional), it didn't work unfortunately, I'm getting the following error:

ERROR: transport error 202: connect failed: Connection refused
ERROR: JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510)
JDWP exit error AGENT_ERROR_TRANSPORT_INIT(197): No transports initialized [debugInit.c:750]
0

I tried replacing server=n by server=y in the command line argument, the error disappeared but now I'm stuck with "Listening for transport dt_socket at address: 9990" and the tests never start. Setting suspend to n launches the tests but my break points don't work.

0

Looks like the port is occupied by another process. Maybe jvm of previous test run is still alive? You may try to change a port number.

EDIT: It was an answer to your previous comment.

0

Test should have "server=n" and connect to debugger as a client, that's the point. 

0

Thanks for the hints, the workflow I described in my initial post using the same port still works so there shouldn't be another process occupying it.

Here's actually the full error I receive when I set "server=n"

ERROR: transport error 202: connect failed: Connection refused
ERROR: JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510)
JDWP exit error AGENT_ERROR_TRANSPORT_INIT(197): No transports initialized [debugInit.c:750]
[error] Could not accept connection from test agent: class java.net.SocketException: Socket closed
java.net.SocketException: Socket closed
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
at java.net.ServerSocket.implAccept(ServerSocket.java:545)
at java.net.ServerSocket.accept(ServerSocket.java:513)
at sbt.ForkTests$$anonfun$mainTestTask$1$Acceptor$2$.run(ForkTests.scala:46)
at java.lang.Thread.run(Thread.java:748)

I tried then setting "onthrow=java.net.SocketException" in the vm commandline args, it generated the following error:

ERROR: JDWP Specify launch=<command line> when using onthrow or onuncaught suboption: -agentlib:jdwp=transport=dt_socket,server=n,address=alayouni-HP-Z420-Workstation:9990,suspend=y,onthrow=java.net.SocketException
[error] Could not accept connection from test agent: class java.net.SocketException: Socket closed
java.net.SocketException: Socket closed
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
at java.net.ServerSocket.implAccept(ServerSocket.java:545)
at java.net.ServerSocket.accept(ServerSocket.java:513)
at sbt.ForkTests$$anonfun$mainTestTask$1$Acceptor$2$.run(ForkTests.scala:46)
at java.lang.Thread.run(Thread.java:748)

Googling the "launch" option led me to here, which is very close  to my case since I'm running on linux, however I'm not sure the "screen" command suggested in the first answer would be relevant with IntelliJ.

0
After a few attempts to diagnose what could be causing the failure of my "Listen" debugger config, I just gave up given my limited Linux knowledge.

I ended up creating two separate configurations, the first launches activator in "attach" debug mode, the other attaches to it, then I use the prompt from the first launch config to specify the tests I'd like to run, ideally there would've been a solution to combine both in one config, but it's time to let go.

Thanks again for your help!

0

Please sign in to leave a comment.