Aleksandr Dubinsky Aleksandr Dubinsky - 6 months ago 34
Java Question

Remotely debug unit tests in Netbeans / Maven

I would like to automatically launch and debug unit tests on a remote machine in a Maven project using Netbeans. All the IDE features should work, such as debugging, the output window, etc. The process has to be fully automated with a single click of "Debug Focused Test Method."

Answer

The solution is to replace the mvn command with a custom script which will perform an rsync and an ssh. Through the magic of both tools, it works really well. The current guide is for bash, but the same idea could be implemented in Windows with powershell, groovy, or even cmd. (I tried to use Nashorn, but couldn't find how to get $0, the location of the running script.)

  • In Netbeans directory /usr/local/netbeans-8.1/java/maven/bin/, rename the mvn script:
    • cd /usr/local/netbeans-8.1/java/maven/bin/
    • sudo mv mvn mvn.orig
  • Create new mvn script.

    #!/bin/bash
    
    if [ -z "$REMOTE" ] ; then 
        SCRIPTDIR=$(dirname "$0")
        $SCRIPTDIR/mvn.orig "$@"
    else
        if [ -z "$REMOTE_BASE_DIR" ] ; then
            echo "ERROR: Please set environment variable REMOTE_BASE_DIR to the folder which contains the project directory"
            exit
        fi
    
        PROJECT_DIR=$(basename "$(pwd)")
        #
        PROJECT_DIR=${PROJECT_DIR// /\\ }
        PROJECT_DIR=${PROJECT_DIR//(/\\(}
        PROJECT_DIR=${PROJECT_DIR//)/\\)}
        REMOTE_PROJECT_DIR=$REMOTE_BASE_DIR/$PROJECT_DIR/
        ARGS=
        for var in "$@"
        do
         ARGS="$ARGS \\\"$var\\\""
        done
    
        echo "Syncing project directory..."
        (set -x; rsync -aczhW --progress --delete --exclude '.git' --exclude 'target' $RSYNC_OPTS ./ "$REMOTE:$REMOTE_PROJECT_DIR")
    
        echo "Executing maven..."
        if [ "$REMOTE_PORT" = '${jpda.address}' ] ; then
            (set -x; ssh ${REMOTE} "cd $REMOTE_PROJECT_DIR; mvn $ARGS")
        else
            (set -x; ssh -R $REMOTE_PORT:localhost:$REMOTE_PORT ${REMOTE} "cd $REMOTE_PROJECT_DIR; mvn $ARGS")
        fi
    fi
    
  • Configure the remote machine:
    • Either install mvn, or install Netbeans and put its mvn on the path. I chose the later, but either should be fine.
    • Configure ssh. I won't describe how to do it here. Make sure that AllowTcpForwarding is set to yes or remote in /etc/ssh/sshd_config.
  • Create new Netbeans configuration that will forward all maven actions (including clean & build) to the remote machine:

    • Go into Project's properties
    • Create new Configuration
    • In "Set properties" add:

      Env.REMOTE_BASE_DIR=<directory on the server that will contain your project directory>
      Env.REMOTE=<address of remote machine>
      Env.REMOTE_PORT=${jpda.address}
      Env.RSYNC_OPTS=<optional, but could be another --exclude>
      

    screenshot

  • To use, select the new configuration in the drop-down menu in the toolbar, and invoke any maven goal as usual.

  • I'm still looking for a way to set up this configuration globally. If you know how to do this, please tell me!
  • I should mention that the debug experience works pretty well, thanks to the remote debug capabilities built into the JVM and the version/dependency tracking of Maven and the excellent Maven integration in Netbeans. I really like that you're able to easily step into the code of other projects (and it can resolve specific versions).
Comments