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
-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
"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:
whereprints 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.
stepadvances to the next line of code, stepping into method calls if they are present.
nextadvances to the next line of code, skipping any method calls that might be present.
print EXPRevaluates the Java expression EXPR and prints the result. For example, if there is a local variable named "foo" you can type
print footo 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
step, 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?