Showing posts with label debug. Show all posts
Showing posts with label debug. Show all posts

Sunday, November 21, 2010

Debugging Java PetStore with Glassfish and Eclipse

Once I made PetStore work in Glassfish, I wanted to debug it in Eclipse.

1. I ran asadmin in my application server path:
C:\J2EE\Sun\AppServer\bin>asadmin start-domain

2. In the browser, I ran the application server Admin Console, available in my case at localhost:4848

3. I went to Application Server menu (top left), I chose JVM Settings and I enabled Debug

4. I restarted the Application Server (after enabling Debug and saving this configuration, I noticed the link "Restart needed" top left; I clicked on it, after that I ran asadmin start-domain from the console)

5. I also ran asadmin start-database to start the database for PetStore

6. I started Eclipse (I use version 3.4.1); under Run menu, I chose "Debug configurations ...."; then I chose the PetStore project (which I had created previously in Eclipse) and port 9009 (the default port where Glassfish is listening for debuggers); I also enabled "Allow termination of remote VM"

7. Just for the test, I put a breakpoint in ImageAction.java, method service; then I started the debug configuration created at bullet 6; finally, I navigated in a browser to
 http://localhost:8087/petstore/faces/catalog.jsp
and I clicked a dog under Pets; I could see my breakpoint being hit.

Friday, August 20, 2010

The evil debugger



Let's take a look at the following piece of C# code:





1:  using System; 
2:  using System.Collections.Generic; 
3:  using System.Linq; 
4:  using System.Text; 

5:  namespace ConsoleApplication1 { 
6:    class Program { 
7:      private string myString = null; 
8:      public string MyString { 
9:        get { 
10:          if (myString == null) { 
11:            myString = "Bad string"; 
12:          } 
13:          return myString; 
14:        } 
15:        set { 
16:          if (myString == null) { 
17:            myString = value; 
18:          } 
19:        } 
20:      } 
21:      public override string ToString() { 
22:        return MyString; 
23:      } 
24:      static void Main(string[] args) { 
25:        Program program = new Program(); 
26:        program.MyString = "Good string"; 
27:        Console.WriteLine(program); 
28:      } 
29:    } 
30:  }  


The result, as you would expect should be "Good string" written to the console. That is, when you run it from the command line.
Suppose I run it in Visual Studio .NET 2008 and I put a breakpoint at line 27 in the debugger. Then I debug the program, I reach line 27, I move to line 28 and the result is of course "Good string".
Let's put a breakpoint at line 26. You'd say "what does the breakpoint have to do with the result ?" Well, it does, because in this case, "Bad string" will be displayed. This is like Heisenberg principle (or the observer effect), isn't it ? When we debug, we actually influence the result. This is possible because when the breakpoint is set at line 26, MyString getter is executed and in effect myString is set to "Bad string". After that trying to set myString to "Good string" can't succeed because in the setter the test (myString == null) is false. At line 27 ToString() is called, displaying of course "Bad string".

The default behavior of the debugger in Visual Studio .NET 2008 is to evaluate the properties when the debugger hits them. Also, the ToString() method is called by default whenever you hover with the mouse pointer over an instance (like "program" in line 26).
You can disable these behaviors under Tools -> Options -> Debugging -> General.

It's good to know this, because as you can see, .NET properties and ToString() evaluation in VS.NET can give you lots of headaches.