javadebuggingjvmtijdwp

Java JVMTI doesn't work alongside -Xdebug -Xrunjdwp


I spent the last 4 hours trying to set up Eclipse TPTP memory profiling on a Tomcat instance that must be run remotely (i.e. not in Eclipse). This should be possible according to the TPTP and Agent Controller docs.

I installed the TPTP components (4.6.0) into my Eclipse (Galileo) workbench, along with the Agent Controller according to the instructions on the website. To enable the agent, I added the following options to the command line that starts the Tomcat instance:

-agentlib:JPIBootLoader=JPIAgent:server=enabled;HeapProf:allocsites=true

and added the following directories to the front of the PATH:

D:\dev\tools\ac\plugins\org.eclipse.tptp.javaprofiler
D:\dev\tools\ac\bin

When attempting to start Tomcat I consistently got the following error message:

ERROR: JDWP unable to get necessary JVMTI capabilities. ["debugInit.c",L279]

I did a lot of Googling but found nothing relevant; I tried reinstalling TPTP and various versions of the Agent Controller.

In the end the problem turned out to be that I was starting Tomcat with the "jpda" option, which catalina.bat translates into

-Xdebug -Xrunjdwp:transport=.....

Removing the "jpda" command argument caused JVMTI to start working.

SO, the question is: I found nothing during any of my searches to indicate that a JVMTI agent is incompatible with debugging. Can someone explain what is going on and why JVMTI + JDWP is not a valid setup?


Solution

  • None of the answers so far are correct and this is the first hit that comes up on Google if you query the error mentioned, so I feel some clarification is needed.

    JVMTI and JDWP do work together, in fact they generally must be used together. You will get ERROR: JDWP unable to get necessary JVMTI capabilities if -Xrunjdwp (and/or possibly -agentlib:jdwp) is specified more than once on the command line. To fix it, make sure you only have one of -Xrunjdwp or -agentlib:jdwp in your command line.

    For more details, read on...

    JVMTI (Java Virtual Machine Tool Interface) is the successor to JVMDI (Java Virtual Machine Debug Interface) and JVMPI (Java Virtual Machine Profiling Interface). It incorporates the functionality of both JVMDI and JVMPI, both of which were deprecated in Java 5 and removed in Java 6. It is the API that exposes the internals of the JVM for the purposes of debugging and profiling.

    JDWP (Java Debug Wire Protocol) is a protocol that describes a simple mechanism for transmitting commands and responses. As far as I know, it is the only way for a debugger sitting outside the JVM to communicate with it and to interface with the JVMTI.

    JDI (Java Debugger Interface) is a client-side (debugger-side) API which exposes some of the features of JVMTI while making use of JDWP more or less transparently.

    The bug mentioned in Bob Dobbs's answer concerns the misleading error message, and the fact that the JVM will try to load JDWP once for every time it is specified on the command line. It doesn't state anywhere that JDWP and JVMTI cannot be used together.

    More info here: https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/rzaha/jpdebuga.htm