IDEs and Remote Debugging
This page is a work-in-progress.
Local port forwarding and proxy
Note: the vagrant-dryad environment has an open JDWP port, so no port-forwarding is necessary to debug that environment.
Tomcat runs with JVM debugging and remote management functionality enabled, as can be seen from a ps entry for Tomcat running on secundus:
dryad 13397 87.1 15.6 10064376 5159976 ? Sl 12:35 3:30 /usr/java/latest/bin/java ... -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=6969 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -agentlib:jdwp=transport=dt_socket,address=8888,server=y,suspend=n
If these ports are not exposed by machines, whether production or development, they must be forwarded to be attached to with local tools. To forward the JDWP port for Tomcat, log into the machine (here, secundus) by ssh and bind the local JDWP port to the remote one:
ssh -L 8888:localhost:8888 $USER@secundus.datadryad.org
This command connects to the remote machine, establishing a SOCKS proxy at port 9696 (an arbitrary port number), which is useful for JMX monitoring:
ssh -v -D 9696 $USER@secundus.datadryad.org
Debugging unit tests
The vagrant test script bin/test_dryad.sh may be updated as follows to enable debugging over JDWP during unit testing:
mvn clean package -DskipTests=false -Dmaven.test.skip=false -Ddefault.dspace.dir="$TEST_DIR" -Dmaven.surefire.debug="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -Xnoagent -Djava.compiler=NONE"
Once the package task has begun, the test runner will pause and prompt that it is waiting for a connection over port 8000. Once a connection is made, for example, with a debugger built into an IDE, testing will resume. Debugging of Java code (test or non-test source) may proceed as normal.
To create a debugging configuration for an application, open IntelliJ to a repository that has code at the same version as was used to build the remote application. In IDEA, select Run -> Debug ... -> Edit Configurations ... -> + -> Remote. In the new debug configuration that opens, update Host and Port to the relevant values for the given environment (see below). The "Command line arguments for running remote JVM" value should be the same as was used to start Tomcat with remote debugging enabled, e.g.:
and it should update automatically. Select Apply to save the configuration.
To start a debugging session, put a breakpoint in the code at the desired location by clicking next to the line number (which should cause a red dot to appear), then select the bug icon. Once the remote application reaches execution at the breakpoint, the debugger will highlight the current line of execution, which can then be advanced by pressing, e.g., the F7 key to step into the command or F8 key to step over it. The stop button in IntelliJ (red square) will exit the debugging session and allow the remote application to resume non-debug execution.
Dev and prod servers
The port value for dev and prod servers may be found by executing `ps` on the machine to be debugged. An example `ps` entry for secundus.datadryad.org may be seen above. Once port-forwarding is established with the remote machine, the debugging host is "localhost". For example, to debug secundus.datadryad.org, set host to "localhost" and port to "8888".
A vagrant-dryad environment has its JDWP port (8000) forwarded by default in the Vagrantfile config, so no ssh port forwarding is required to debug Tomcat there. However, Tomcat must be started in debug mode, which may be done by executing the startup script '~/dryad-tomcat/bin/startup-debug.sh'. Once Tomcat is running in debug mode, it may be debugged using host "192.168.111.223" and port "8000".
VisualVM is a profiling tool that enables inspection of JVM runtime properties such as heap activity or CPU usage. VisualVM may be attached to a remote JVM, as long as the VM was started with remote management (e.g., JMX) enabled.
VisualVM will automatically detect JVMs running on its local environment. To add remote JVMs for monitoring, right-click "Remote" and select "Add remote host...". Enter the hostname of the remote host, then click OK. Once the name of the remote host appears, right-click it and select "Add JMX connection...". Enter the name of the host and the JMX port under Connection then click OK. If successful, an entry will be added for the running JVM session. Double-clicking that entry will allow the running JVM to be monitored.
Dev and prod servers
To run VisualVM against a remote dev or prod server, first set up a SOCKS proxy (see above, using port 9696). Then in VisualVM, go to Preferences -> Network. Select "Manual proxy settings", then enter "localhost" and "9696" under SOCKS proxy. Click OK.
When using a SOCKS proxy, the name of the remote host is its actual name, not "localhost". For example, to profile secundus, use "secundus.datadryad.org" as the new remote host. The name of the host and port for the JMX connection for secundus is "secundus.datadryad.org:6969". (Note that the SOCKS proxy must be actively running for the connection to be made.)
Two steps are required to enable JMX management for a Vagrant environment: (1) open a JMX port for the Vagrant VM, (2) pass JMX configuration to Tomcat startup. Below, "6969" is used for the JMX port.
To open a JMX port, add the following line to the Vagrantfile and restart the Vagrant VM:
config.vm.network "forwarded_port", guest: 6969, host: 6969
To enable JMX options in Tomcat, export relevant values before startup:
$ export JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=6969 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=192.168.111.223"
A remote profile for the Vagrant Tomcat JVM may be created using hostname "192.168.111.223" and a JMX Connection "192.168.111.223:6969".
Note that if the network settings for VisualVM have been updated to use a SOCKS proxy, the host "192.168.111.223" must be added as a "no proxy host" in the VisualVM network options.
Enabling JPDA Debugging
See Tomcat FAQ for details on configuring for remote debugging. Tomcat will default to JPDA on port 8000, server=y, transport=socket, and suspend=n
On a mac
catalina jpda start
On vagrant vm