How to debug a remote Scala app?

Good day.

I am interested in learning how to debug a remote Scala app that is run via JavaExec in gradle.

I have this gradle.build file

apply plugin: 'scala'
  project.ext.scalaVersion = "2.9.2"
project.ext.mySqlVersion = "5.1.21"
project.ext.lambdaWorksVersion = "1.3.2"
project.ext.commonsCliVersion = "1.2"
  task slurp(type: JavaExec, dependsOn: classes) {
    main = 'slurper.App'
    args = System.getProperty("args", "").split().toList()
    classpath sourceSets.main.runtimeClasspath
}
  dependencies {
    // Libraries needed to run the scala tools
    scalaTools "org.scala-lang:scala-compiler:$project.scalaVersion"
    scalaTools "org.scala-lang:scala-library:$project.scalaVersion"
      // Libraries needed for scala api
    compile "org.scala-lang:scala-library:$project.scalaVersion"
      // MySQL
    compile "mysql:mysql-connector-java:${project.mySqlVersion}"
      // Scrypt
    compile "com.lambdaworks:scrypt:${project.lambdaWorksVersion}"
      // Commons CLI
    compile "commons-cli:commons-cli:${project.commonsCliVersion}"
}
  repositories {
    mavenCentral()
}

I then configure Java remote debugging like this:

export GRADLE_OPTS="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=4000,server=y,suspend=y"

I then configure my IDE, set a breakpoint, start my app via “gradle slurp …” per my build file task, and connect the debugger to the remote JVM.

This much works, as I see the app suspend, then continue when the debugger attaches.

But the app does not stop at a breakpoint I know the code traverses.

I suspect I am missing something in the build file.

Can anyone help?

Thank you.

‘JavaExec’ forks its own JVM, so you’ll have to debug that instead of the Gradle JVM. You can pass the debug args to ‘JavaExec.args’.

Thank you.

I believe this works, too: arrange to set the debug property on the task with a system property.

task slurp(type: JavaExec, dependsOn: classes) {
    main = 'slurper.App'
    args = System.getProperty("args", "").split().toList()
    debug = Boolean.valueOf(System.getProperty("debug", "false"))
    classpath sourceSets.main.runtimeClasspath
}

Sure, as long as you set the system property accordingly.

Just curious: Is it possible to succinctly set a task property from the command line, like with this near-pseudocode?

gradle --JavaExec.debug=true slurp …

or

gradle --slurp.debug=true slurp …

where the token following the “–” is the task name.

No, there isn’t yet a generic way to do so. It’s a planned feature though.