I am working on some JRuby code that calls third-party Java libraries. The Java libraries were behaving oddly so I wanted to run them under JDB, the Java Debugger, so I can step through them line by line and inspect important values.
In Linux and Mac OS X, I think you should be able to do this by passing the --jdb
option to JRuby when you run it. In Windows, JRuby does not support that option, but I was able to figure out how to do it anyway. Here is the command I used:
"C:/Program Files/Java/jdk1.7.0_45/bin/jdb.exe" -classpath "C:/jruby-1.7.4/lib/jruby.jar" -Djruby.home="C:/jruby-1.7.4" org.jruby.Main
The -classpath
argument to JDB allows it to find the jruby.jar file, which defines jruby's org.jruby.Main class, which is the class to start if you want to use JRuby. The -Djruby.home
option is recognized by JRuby and allows it to find its libraries and gems. If you want to pass any arguments to JRuby, then you can add them on to the end of this command, after org.jruby.Main. For my situation, I wanted to run RSpec so I added -S rspec
:
"C:/Program Files/Java/jdk1.7.0_45/bin/jdb.exe" -classpath "C:/jruby-1.7.4/lib/jruby.jar" -Djruby.home="C:/jruby-1.7.4" org.jruby.Main -S rspec
Once you have started JDB successfully, you should see a message like "Initializing jdb ..." and a command prompt on the next line. My basic workflow is that I would figure out what class and method I want to inspect, and then I would add a breakpoint for it by running a command like this:
stop in com.example.namespace.ExampleClass.exampleMethod
Then run the run
command. The JRuby and Java code will run until the specified breakpoint is hit, at which point the debugger will stop and let you interact with it again. Here are some more common commands I use:
where
prints a full stack trace. These tend to be very long because of the internals of JRuby but if you scroll to the top you can see what part of the Java code you are in.step
advances to the next line of code, stepping into method calls if they are present.next
advances to the next line of code, skipping any method calls that might be present.print EXPR
evaluates the Java expression EXPR and prints the result. For example, if there is a local variable named "foo" you can typeprint foo
to see its value.
- It would be nice to have a JDB command that prints out the current filename, method name, and line number. You get this info whenever you run
next
orstep
, but sometimes that output ends up really far up in my buffer and I would like a way to quickly see that information again. - It would be nice to do this inside some kind of an graphical interface or IDE. Has anyone gotten that working?