Tuesday Oct 21, 2008

Cross-language debugging: from Ruby to Java and back

Until we bring the full support for two ways debugging - from Ruby to Java and vice versa; the following "trick" might be used to debug Ruby and Java at once in the NetBeans 6.5 (you might get 6.5 build here). It might be used to debug standard JRuby applications/scripts, JRuby's Java extension or JRuby's internals itself. I'm using it for some time during development of JRuby Fast Debugger extension.

The trick is to start actually two debugging sessions, one for Ruby part and second for Java part (JVM under which JRuby runtime runs). Sessions then automatically activate themselves when the breakpoint for their language is hit.


Except the Ruby IDE, we need to have Java support installed if it is not already the case. This can be find out by looking e.g. into the New Project Wizard. If the Java category is there, we have all we need. If not see the How do I install the Java support into the Ruby NetBeans IDE? FAQ.

So how to utilize it

  1. Open a (J)Ruby project utilizing some Java classes
  2. Go to its properties -> Run category and set JVM Arguments to -Xdebug -Xrunjdwp:transport=dt_socket,address=7000,server=y,suspend=y like on the screenshot (for Rails project the field has to be edited through properties file manually).

    JVM Arguments
  3. Then set the breakpoints in the Ruby code and Java code
  4. Start to debug the (J)Ruby project: Menu | Run | Debug Project
  5. Connect to the JRuby's JVM session: Menu | Debug | Attach Debugger, enter the port 7000, confirm the dialog. (Note that this need to be done within 15 seconds after the Ruby debugger was triggered (previous step). If that's not enough for you, you might increase the Ruby debugger timeout)

    Attach Debugger

That's it. As can be seen on the following screenshot, after I do a step in the Ruby code, Java debugging session take over the control and I'm debugging the Java code called from Ruby code with the full power of NetBeans Java debugger. Once I'm done with Java side I'll just press F5 (Continue) and Ruby debugging session takes back the control and I can continue with the debugging of Ruby part.
Note that if you have JRuby sources you might just set the breakpoint somewhere in the JRuby interpreter's guts and take a look what going around in there.


Clearly not fully-fledged cross-language debugging. Since sessions live their life independently, actions like Step Into, Step Over and similar do not work in the cross-language context. We have to simulate Step Into and similar actions by putting breakpoints on appropriate places. Stacktrace is not shared, so we get two, one for each language, instead of one with nicely mixed frames from both languages. But still, I find it pretty handy during JRuby Fast Debugger development.
If you do not want to repeatedly delete and add the long string from the step 2, you might create a configuration as might be seen in the properties screenshot (JRuby Debug in Configuration combobox).

To watch the progress on fully-fledge cross-language debugging, you might CC yourself to this RFE in the Issuezilla.

Friday Jun 13, 2008

JRuby Fast Debugger 0.10.1

Friday the 13th, the good time for a new release :), here it is:


  • Main feature or benefit is that all the new features of MRI's CLI fast debugger might now be utilized. See CHANGES and Changelog for ruby-debug 0.10.1 release and check Debugging with ruby-debug manual. Rocky Bernstein pushes the CLI interface to be compatible with, or similar to, the one used for gdb. So be sure to check the CHANGES or type 'help' command into debugger console to check the new commands or the ones whose behaviour have changed.
  • No -J-Djruby.reflection=true -J-Djruby.compile.mode=OFF monster is needed any more. JRuby 1.1.2 (see JIRA 2474 for details) comes with special flag for debugging. Now all is needed is to pass --debug parameter to JRuby. So to debug your application, you just need to run:
      jruby --debug -S rdebug <your-script>
  • ruby-debug-base since version 0.10.1 depends on other native gem - linecache. With jruby-debug-base this is not needed since we are workarounding this by dummy linecache fake directly in jruby-debug-base. This means that we are not as clever as C ruby-debug-base - particularly in JRuby debugger you might put breakpoint on lines with no executable code where C implementation would cleverly reject it. In future there will be hopefully decent implementation of linecache. Any volunteer? :)
  • we are now passing almost whole, little bit tweaked, test suite of MRI ruby-debug 0.1.10. Few patches were contributed to ruby-debug-base implementation independence (whether it is MRI, JRuby or Rubinius one). Thanks ruby-debug team for the great test suite. This helps stability and compatibility of all implementations.
  • following up from the above point several bugs were fixed.
  • see ChangeLog for details.

Good to know

Since there were some API changes in JRuby 1.1.2 the jruby-debug-base 0.10.1 release does not work with JRuby 1.1.1 and older, only with JRuby 1.1.2+.


For installation see debug-commons website or Using the JRuby Debugger on JRubyWiki.

Enjoy and any feedback is welcomed as always.


Martin Krauskopf


« June 2016