Remote debug with Java and Eclipse

Suppose you need to debug a program. A program that written in Java. You may say: "What can be easier? I do it every day! Actually I do it all the time that I spent at work". That's true if you work as a java developer you know that everything you should do to debug your program is to click on the "green bug" icon on the top and select a main class (If you are running Eclipse ;), in other IDEs it can be even easier). Really, what can be easier? But what if you need to debug a program that wasn't written by you? Moreover, what if it runs not on your local machine (for example on some machine within your local network)? Those people who know how to do this can stop reading at this point :) …

So you do not know or trying to learn more about it, you may continue :)

OK. Lets try to do it :) Here is an example of a simple program that we want to be debugged:

package org.iforge.aectann;
 
public class DebugMe {
    public static void main(String[] args) throws Exception {
        int i = 1;
        i++;
        throw new Exception();
    }
}

Very simple, but suppose we really need to stop the execution before an exception is thrown. For example we want to know the value of i. And here is the steps you should follow to get it.

First of all we need to tell a VM run in debug mode. This can be easily done by passing appropriate parameters to command line, when starting our application, here is an example:

java -agentlib:jdwp=transport=dt_socket,server=y,address=8000 org.iforge.aectann.DebugMe

After running it you should see something like that:

Listening for transport dt_socket at address: 8000

Great, we have ran our app in debug mode, and it is waiting us to start debugging. Let's go and start it ;) Go to Eclipse and open debug dialog (you can press Alt+R, B). Create a new Remote Java Application Configuration. Select connection type as "Socket attach" and specify Connection Properties (for our example host would be localhost, and port would be 8000).

debug.png

That's all, press the debug button. You'll see the debug perspective with the program suspended on the line that throws an Exception.

debug1.png

"Stop! I do not see my program!" - If the only thing you see is a debug perspective with text "Source not found" it means that you need to stop program execution and go back to the Debug Configuration page. Switch to the second tab ("Source") and add a folder or a project (or an archive) that contains sources of your program.

debug2.png

Then start the program again and retry.

That is quite a simple example and in a real life you do not need to debug such programs. And I have one more complex example for you. One day I was asked to write a simple mailet for James server. James is a Java Mail server that is supported by Apache Foundation, and Mailet is just a mail handler that performs some operations on incoming messages (For more information about James see home site). So we need to debug our mailet and probably we need a possibility to debug James itself. Here is several simple steps to reach it:

  1. Get James binary distribution and sources.
  2. Extract binary distribution
  3. Go to bin directory and change run.bat file (or phoenix.sh if you run on Unix-like OS)
  4. Somewhere in the top of file add PHOENIX_JVM_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,address=8000"
  5. Go to eclipse and add debug configuration to your mailet project as described in example
  6. That's all. If you also want to debug James itself, create new project for James and add James sources there, add libraries that included in source distribution to the project classpath (do not forget add James project to the sources of Debug configuration).
    james-mailet.png
  7. Run James, either by run.bat or by run.sh file.
  8. Run debug within Eclipse.
  9. Vuala! You now can toggle breakpoints in your mailet code and even in the James code.
    james-mailet2.png
Bibliography
1. Sun's JDPA connection and invocation. Contains many useful examples and description of command line parameters.
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License