title: How does one trace recursive calls using the Java Debug Interface?
body: <p>How does one utilize the <strong>Java Debug Interface</strong> to trace the recursive calls that presumably will be made in evaluating the expression <code>Main.reverseString ( args[0] )</code> in file <code>Main.java</code>?</p>
  
  <p>Here is the file <code>Main.java</code> :</p>
  
  <pre><code>public class Main
    {
    public static void main ( String [] args )
      {
      System.out.println ( "args[0] ..... " + args[0] ) ;
      String reversed = Main.reverseString ( args[0] ) ;
      System.out.println ( "reversed .... " + reversed ) ;
      } // main
    public static String reverseString ( String s )
      {
      if ( s.length() &lt;= 1 )
        return s ;
      return ( (new StringBuilder(reverseString(s.substring(1))))
                                .append(s.charAt(0)).toString() ) ;
      } // reverseString
    } // Main
  </code></pre>
  
  <p>My tracing program (<code>RecursionTracer</code>) is shown below :</p>
  
  <pre><code>import com.sun.jdi.* ;
  import com.sun.jdi.connect.* ;
  import com.sun.jdi.request.* ;
  import com.sun.jdi.event.* ;
  import java.util.* ;
  
  public class RecursionTracer
    {
    public static void main ( String [] args ) throws Exception
      {
      LaunchingConnector launchingConnector
        =  Bootstrap.virtualMachineManager().defaultConnector() ;
      Map&lt;String, Connector.Argument&gt; env
        =  launchingConnector.defaultArguments() ;
      env.get("main").setValue ( Main.class.getName() ) ;
      VirtualMachine vm = launchingConnector.launch(env) ;
  
      ClassPrepareRequest classPrepareRequest
        =  vm.eventRequestManager().createClassPrepareRequest() ;
      classPrepareRequest.addClassFilter ( Main.class.getName() ) ;
      classPrepareRequest.enable() ;
  
      EventSet eventSet = null ;
      do
        {
        eventSet = vm.eventQueue().remove() ;
        for ( Event event : eventSet )
          {
          if ( event instanceof ClassPrepareEvent )
            {
            MethodEntryRequest methodEntryRequest
              =  vm.eventRequestManager().createMethodEntryRequest() ;
            methodEntryRequest.addClassFilter ( Main.class.getName() ) ;
            methodEntryRequest.enable() ;
            } // if ClassPrepareEvent
  
          if ( event instanceof MethodEntryEvent )
            {
            System.out.println ( "\n--------------------------------------" ) ;
            MethodEntryEvent methodEntryEvent = (MethodEntryEvent) event ;
            com.sun.jdi.Method method = methodEntryEvent.method () ;
            System.out.println ( "MethodEntryEvent has occurred ..." ) ;
            System.out.println ( methodEntryEvent ) ;
            System.out.println ( method ) ;
            System.out.println ( "======================================\n" ) ;
            } // if MethodEntryEvent
  
          vm.resume() ;
          } // for each event
        }
      while ( eventSet != null ) ;
      } // main
    } // RecursionTracer
  </code></pre>
  
  <p>I compile both <code>Main.java</code> and <code>RecursionTracer.java</code> as follows :</p>
  
  <pre><code>del *.class
  D:\Java\JDK-11~1.1\bin\javac.exe -g Main.java RecursionTracer.java -Xlint:unchecked
  </code></pre>
  
  <p>When I run the <code>RecursionTracer</code>, its output is :</p>
  
  <pre><code>D:\&gt;D:\Java\JDK-11~1.1\bin\java.exe RecursionTracer
  
  --------------------------------------
  MethodEntryEvent has occurred ...
  MethodEntryEvent@Main:5 in thread main
  Main.main(java.lang.String[])
  ======================================
  
  Exception in thread "main" com.sun.jdi.VMDisconnectedException
      at jdk.jdi/com.sun.tools.jdi.EventQueueImpl.removeUnfiltered(EventQueueImpl.java:200)
      at jdk.jdi/com.sun.tools.jdi.EventQueueImpl.remove(EventQueueImpl.java:97)
      at jdk.jdi/com.sun.tools.jdi.EventQueueImpl.remove(EventQueueImpl.java:83)
      at RecursionTracer.main(RecursionTracer.java:26)
  </code></pre>
  
  <p>I had expected to see <code>MethodEntryEvent</code>s occur each time method <code>Main.reverseString</code> is entered, but, as one can see from the above output, the only <code>MethodEntryEvent</code> is when execution enters <code>Main.main</code>.  Why are there not also <code>MethodEntryEvent</code>s displayed for <code>Main.reverseString</code>?  Moreover, how can I get such <code>MethodEntryEvent</code>s to be displayed? Finally, it would be nice to see the argument that is supplied to <code>Main.reverseString</code> with each invocation of that method.</p>