Chapter 14

Utilizing the Visual Debugger in Cafe


CONTENTS


Today is the last day of your second week with this book. Today's topic will primarily give you an introduction to debugging in Symantec Café.

The topic of debugging in general is a fairly advanced one. That is why it has not even been introduced until today. And notice that today will be more of an introduction to this field than anything else. For those of you who have never used a professional debugger before, today's activity will give you a chance to get your feet wet. And for those who have more experience in programming, it will give you a chance to see how Java (and Symantec Café) handles errors. The primary idea behind this chapter is that in the real world when you develop applications, you will receive errors, and it often is more important for a programmer to handle errors in code than to attempt to write perfect code the first time.

In today's text you'll get into the following activities:

Note
This chapter is designed to be used with Symantec Café version 1.0 and is compatible with version 1.2. Several enhancements were made to the debugger in version 1.2-most notably a significant speed improvement in the debugger and breakpoints that is supported in runtime. Check the readme file in Café 1.2 for more information.

Debugging a Project

The first thing to note before you can begin debugging is that for the Java debugger to even work, you must have TCP/IP installed. Obviously, if your computer works with other
TCP/IP software, such as your browser, you should have no problem. For more information, consult the readme file that comes with Symantec Café.

Note
Café version 1.2 does not require TCP/IP for local debugging sessions.

After that is accomplished, you should be able to debug your projects. The Symantec Café Debugger gives you the ability to completely debug your Java programs. You can go line by line, stepping conditionally into and over your code.

Working with Errors in Java and Symantec Café

Before having you dive into debugging in Java, in the next few sections I cover what an error message looks like and how you can resolve error messages. The project HelloDebug is based on the applet you created at the beginning of this book. Fundamentally, this project is meant to display the words Hello World on its main applet pane. This time, however, it will be jury-rigged, if you will, with a few very basic errors. Right now, use Table 14.1 to create the project HelloDebug in the appexpress.

Table 14.1. Information for the appexpress to create project HelloDebug.
StepActions Needed
1. Application TypeApplet
2. Select Directory  \Cafe\Projects\HelloDebug
3. MiscellaneousProject Name: HelloDebug
4. NamesNo Changes
5. File NamesNo Changes
6. Help OptionsNot Available

Figure 14.1 shows the Project window for the project HelloDebug. Double-click the file HelloDebug.java to edit it.

Figure 14.1 : The Project window for HelloDebug.

Listing 14.1 shows the highlighted areas that need to be added to the file HelloDebug.java. Go ahead and make the additions, and then save the file.


Listing 14.1. HelloDebug.java with two errors.
1: /*
2:    This class is a basic extension of the Applet class.  It would generally
                Âbe
3:    used as the main class with a Java browser or the AppletViewer.  But an
       Âinstance
4:    can be added to a subclass of Container.  To use this applet with a
       Âbrowser or
5:    the AppletViewer, create an html file with the following code:
6:
7:    <HTML>
8:    <HEAD>
9:    <TITLE> A simple program </TITLE>
10:    </HEAD>
11:    <BODY>
12:
13:    <APPLET CODE="HelloDebug.class" WIDTH=332 HEIGHT=169></APPLET>
14:
15:    </BODY>
16:
17:    </HTML>
18:
19:    You can add controls to HelloDebug with Cafe Studio.
20:    (Menus can be added only to subclasses of Frame.)
21: */
22:
23:import java.awt.*;
24:import java.applet.*;
25:
26:public class HelloDebug extends Applet {
27:
28:    public void init() {
29:
30:        super.init();
31:
32:        //{{INIT_CONTROLS
33:        setLayout(null);
34:        resize(230,190);
35:
36:        //My code starts here
37:        Font f = new Font("Helvetica, Font.BOLD, 36);
38:        setFont(f);
39:
40:        //label1=new Label("A Simple Applet");
41:        //add(label1);
42:        //label1.reshape(61,73,98,15);
43:        //My code ends here
44:
45:        //}}
46:    }
47:
48:    //My code starts here
49:    public void paint(Graphics g) {
50:            g.drawString("Hello World", 50, 50)
51:    }
52:    //My code ends here
53:
54:    public boolean handleEvent(Event event) {
55:        return super.handleEvent(event);
56:    }
57:
58:    //{{DECLARE_CONTROLS
59: Label label1;
60:    //}}
61:
62:}

Looking at Listing 14.1, you might have already noticed in the highlighted areas that this code contains two mistakes. The first error is on line 37: In the declaration of the font, the terminating quotation mark is missing. And in line 50, the semicolon at the end of the statement is missing as well. Now, in theory, someone new to programming would deduce that if there is one error in the code, only one error message should be shown by the compiler. In the real world, however, no one has been able to develop a compiler to that level of intelligence, as you shall see in a moment.

Warning
The applet in Listing 14.1 will not compile without errors.

Understanding Error Messages in Java and Symantec Café

Compile the HelloDebug project. Let me remind you again that this project is currently not meant to compile. But it is meant as a learning exercise, and unless you did something wrong, it should not compile. Figure 14.2 shows an enlarged Output window of what you should see when you attempt to compile the project.

Figure 14.2 : The Output window for the project HelloDebug.

If you have not been trying the examples, or if you have typed each example perfectly in the first two weeks of this book, this might be the first time you have seen what an error message looks like in Java. So, under the assumption that you have never seen an error message before, Table 14.2 briefly explains each part of the first error message.

Table 14.2. The syntax of an error message.
Dissection of Error

Error: C:\Cafe\Projects\HelloDebug\HelloDebug.java(37): String not terminated at end of line
ErrorExplanation
Error Specifies whether the following message is an Error or a Warning
..\HelloDebug.java Indicates the file where the error occurred
(37) Specifies the line number
String not terminated at end of line Gives an error description

Now, looking more closely at the Output window, you should also notice that the compiler returned seven errors. And some of these errors are on line numbers that were assumed to be bug free. This can be one of the most frustrating parts of programming in any language because the compiler reports errors all over the place when there is truly only one error at the top of the page. Do not be discouraged, however, because what you must do is look more closely at what each error message is saying. Do not take it at face value, but instead look for a pattern. That's exactly what you'll do in this example.

Note
It is not uncommon for even an advanced compiler to report more than one error at other locations when the code actually contains only one physical error. As you continue to develop more complex applications, you will notice this gap increase. For example, it is possible to have 65 error messages when there is truly only one error. In cases like this, you would first want to look at your declarations because what most likely happened is that you incorrectly declared something (for example, a class or variable) that was used 64 times throughout the program.
Although a 65-to-1 ratio is rare, the important thing to remember is to find a pattern or similarity among the messages and see where they are pointing to in the physical code.

Now I'll demonstrate the capabilities of Symantec Café by having you double-click the first error message, which is as follows:

Error: C:\Cafe\Projects\HelloDebug\HelloDebug.java(37): String not terminated at end of line

Notice that Symantec Café opens the Source Window Text Editor containing the class where the error is located. It also highlights in red the actual line of code the compiler tripped on. And it displays the error message in the status bar at the bottom of the screen, as shown in Figure 14.3.

Figure 14.3 : Finding errors in Symantec Café.

Go back to the Output window, and double-click some of the other error messages. See where they are going in the code, and read each message. Now I'll help you understand what the compiler is trying to convey. The first error message you received is indicating that you did not terminate the line of code. At first glance, this does not make sense, because if you look at line 37, you can see that it has a semicolon at the end. So your next question should be, "What would cause the compiler to skip over the semicolon?" Answer: the unbalanced quotation marks. You see, without the terminating quotation mark, the compiler thinks that everything after Helvetica is part of the string literal. That is also why the next error message was generated, because for the same reason the compiler could not find the closing parenthesis:

Error: C:\Cafe\Projects\HelloDebug\HelloDebug.java(38): ')' expected

The next two errors are generated because line 37 does not have a proper termination. So now that you see a physical error in the code and you also see that several of the error messages are pointing to that line of code, go ahead and add a closing quotation mark in line 37:

Font f = new Font("Helvetica", Font.BOLD, 36);

After you have corrected that mistake, recompile the project. You should then see something like what's shown in Figure 14.4.

Figure 14.4 : The Output window for project HelloDebug on the second try.

Looking at Figure 14.4, double-click each of the two messages, and you will see that the first message hit a bull's-eye by stating that it was looking for a semicolon at the end of this line but did not find one. The second error message was generated because the compiler was trying to understand how the following line of code (excluding comments, because they are not read by the compiler) and the preceding line of code would work together.

Add a semicolon to line 50, save, and recompile. This time, you should see Successful Build, as shown in Figure 14.5.

Figure 14.5 : The Output window for project HelloDebug on the third try.

At this point, you have successfully removed the errors from this program. Execute the applet, and you should see the words Hello World displayed on the applet pane. Figure 14.6 shows what you should see when the project is executed.

Figure 14.6 : Project HelloDebug successfully executed.

Using Symantec Café's Debugging Tools

One of the most complex errors to remove from an application is one that has no syntactical error and so compiles without a problem. But when you attempt to execute the program, it does not do what is was meant to do. In this section, I will give you an introduction to several tools, some of which might seem overwhelming. But in situations like the one just mentioned, these tools can be very handy in helping you find a problem in your code. Although a detailed discussion of debugging is beyond the scope of this book, the next several sections introduce each of these tools and give you a chance to familiarize yourself with them.

I'll start by having you invoke the appexpress and create a new project called ManyWindows, as shown in Table 14.3.

Table 14.3. Information for the appexpress to create project ManyWindows.
Step
Actions Needed
1. Application TypeApplet
2. Select Directory..\Cafe\Projects\ManyWindows
3. MiscellaneousProject Name: ManyWindows
4. NamesNo Changes
5. File NamesNo Changes
6. Help OptionsNot Available

In this example, you are creating an applet that will enable you to open and close windows. The actual lesson, however, will be in looking at this project through the debugger. At this point, simply complete the project. Go ahead and double-click the file ManyWindow.rc to edit it in the Café Studio. Draw two buttons in the applet pane, and edit their specifications in the Properties window as shown in Table 14.4.

Table 14.4. Properties for project ManyWindows in the Café Studio.
Object Member
Property
Value
button1 Caption Open Window
button2 Caption Close Window

At this point, you should see something similar to what's shown in Figure 14.7.

Figure 14.7 : Café Studio for project ManyWindows.

In the Properties window for object button1, go to the Events tab and double-click the clicked event. The Class Editor should open with the method clickedButton1 open for editing. Make the changes shown in Listing 14.2 to the method clickedButton1. Figure 14.8 shows what the Class Editor should look like after you have made the changes to this method's code.

Figure 14.8 : The Class Editor for method ClickedButton1.


Listing 14.2. The code for the clickedButton1 method.
1://}}
2:
3:    public void clickedButton1() {
4:        // to do: put event handler code here.
5:
6:        //My code starts here
7:        if (!window.isShowing())
8:            window.show();
9:        //My code ends here
10:
11: }

Save and close the Class Editor, and go back to the Café Studio. This time, go to the other button, called button2, and in the Properties window in the Events tab, edit the clicked event. When the Class Editor opens, make the changes shown in Listing 14.3. Figure 14.9 shows what the Class Editor should look like when you have finished modifying the method clickedButton2.

Figure 14.9 : The Class Editor for method clickedButton2.


Listing 14.3. The code for the clickedButton2 method.
1:    public void clickedButton2() {
2:            //to do: put event handler code here.
3:
4:            //My code starts here
5:            if (window.isShowing())
6:                window.hide();
7:            //My code ends here
8:    }

After you have made the changes shown in Listing 14.3, save and close the Class Editor. Then save and close the Café Studio. Go back to Project window and open the file ManyWindow.java for editing in a clean Source Window Text Editor. Make the additions or changes shown by the highlighted code in Listing 14.4.


Listing 14.4. The code for ManyWindows.java.
1:/*
2:    This class is a basic extension of the Applet class.  It would generally
       Âbe
3:    used as the main class with a Java browser or the AppletViewer.  But an
       Âinstance
4:    can be added to a subclass of Container.  To use this applet with a
       Âbrowser or
5:    the AppletViewer, create an html file with the following code:
6:
7:    <HTML>
8:    <HEAD>
9:    <TITLE> A simple program </TITLE>
10:    </HEAD>
11:    <BODY>
12:
13:    <APPLET CODE="ManyWindows.class" WIDTH=332 HEIGHT=169></APPLET>
14:
15:    </BODY>
16:
17:    </HTML>
18:
19:    You can add controls to ManyWindows with Cafe Studio.
20:    (Menus can be added only to subclasses of Frame.)
21: */
22:
23:import java.awt.*;
24:import java.applet.*;
25:
26:public class ManyWindows extends Applet {
27:
28:    //My code starts here
29:    Frame window;
30:    //My code ends here
31:
32:    public void init() {
33:
34:        super.init();
35:
36:        //{{INIT_CONTROLS
37:        setLayout(null);
38:        resize(229,190);
39:        label1=new Label("A ManyWindows Applet");
40:        add(label1);
41:        label1.reshape(61,73,98,15);
42:        button1=new Button("Open Window");
43:        add(button1);
44:        button1.reshape(16,23,89,24);
45:        button2=new Button("Close Window");
46:        add(button2);
47:        button2.reshape(121,23,89,24);
48:        //}}
49:
50:        //My code starts here
51:        window = new Frame("A Popup Window");
52:        window.resize(150, 150);
53:        window.show();
54:        //My code ends here
55:
56:    }
57:
58:    public boolean handleEvent(Event event) {
59:        if (event.id == Event.ACTION_EVENT && event.target == button2) {
60:                clickedButton2();
61:                return true;
62:        }
63:        else
64:        if (event.id == Event.ACTION_EVENT && event.target == button1) {
65:                clickedButton1();
66:                return true;
67:        }
68:
69:        return super.handleEvent(event);
70:    }
71:
72:    //{{DECLARE_CONTROLS
73:    Label label1;
74:    Button button1;
75:    Button button2;
76:    //}}
77:
78:    public void clickedButton1() {
79:        // to do: put event handler code here.
80:
81:        //My code starts here
82:        if (!window.isShowing())
83:            window.show();
84:        //My code ends here
85:
86:    }
87:
88:    public void clickedButton2() {
89:            //to do: put event handler code here.
90:
91:            //My code starts here
92:            if (window.isShowing())
93:                window.hide();
94:            //My code ends here
95:
96:    }
97:}

Basically, what you have done is created two buttons. Pressing the first button opens a separate Frame. And pressing the second one closes it. Essentially, there's nothing too new here as far as content.

Execute the project and you should see the main applet window open with the two buttons and the secondary window that can be closed and reopened, as shown in Figure 14.10.

Figure 14.10 : The ManyWindows project executed.

Breakpoints

Now that you have a project to debug and you understand how it works, it's time for you to move forward with today's lesson by working with breakpoints. Looking at the code in ManyWindows.java, you can specify a breakpoint by right-clicking the line of code you want to have the compiler stop at. At the bottom of the popup menu should be a submenu called Breakpoint. Highlight it to expand it. There you should see two options: The top one toggles on or off a breakpoint at the specified line, and the second one clears all breakpoints.

A breakpoint is a location in a program at which execution is halted so that the programmer can review the program's status at that point. Things that could be reviewed by the programmer are the value of certain variables or objects and the number of threads running at this instance of time.

Referencing Listing 14.4 for the file ManyWindows.java, right-click line 47. Then move your mouse down to the bottom of the menu to expand the submenu Breakpoint. Click Set/Clear Breakpoint. Or if you want, you can use the shortcut for toggling a breakpoint by pressing f9 on the line on which you want to toggle a breakpoint. You can tell that the breakpoint has been successfully specified because a red dot appears at the far left of the line, as shown in Figure 14.11.

Figure 14.11 : Specifying a breakpoint.

At this point, you are ready to begin debugging. Click Debug | Start/Stop Debugging in the main menu bar, and Symantec Café automatically moves you to the Debugging workspace, where several windows will close and others will open. After the Debugging mode has completed initialization, you should see something like what's shown in Figure 14.12.

Figure 14.12 : The Debugging workspace.

Your next step in this demonstration is to move the program forward until it hits the breakpoint you specified earlier. You can do that by going back to the Debug menu and clicking Go until Breakpoint.

Now you should notice that all the windows have changed. Also, you should see a change in the Source Window Text Editor for the ManyWindows.java file. A black arrow should be placed over the red dot, as shown in Figure 14.13. This black arrow tells you which line Symantec Café is at in executing the code. The entire line has been highlighted as well to help it stand out. So in this case, Café has stopped execution at your breakpoint (as it should), and now you can take a closer look at some of the windows on the right to see what is going on inside your program.

Figure 14.13 : The execution point at the breakpoint in project ManyWindows.

The Data/Object Window

The first window I'll introduce is the Data/Object window, which is in the upper left corner. The Data/Object window displays all the variables and objects in the program being debugged. This makes it very easy to view the values of your variables and objects, as well as the variables and objects created by the system at the given breakpoint. Take a closer look at the Data/Object window for this project, as shown in Figure 14.14. The Data/Object window structures all of its items into three columns. From left to right, the first column represents the data or object type, the second gives its name, and the third gives the value for that item.

Figure 14.14 : The Data/Objects Window for project ManyWindows.

As you can see in the figure, only one item is shown. In the Data/Object window, however, you can drill down many levels. In fact, right now you are at what would be considered the top level (that is, the variable level). Right-click the highlighted item shown in Figure 14.14, and the following three options should appear:

Double-click the item and you should notice the list of variables and objects underneath. Also, notice that the status bar at the top has changed from init-which, based on your specified breakpoint, is the variable level for the Data/Object window-to init.this. As you continue to drill down, this status bar continues to lengthen, showing you exactly what level you are at, as shown in Figure 14.15.

Figure 14.15 : One level lower in the Data/Object window.

Note
The Call window can update the Data/Object window to display information (see the next section for more information on what the Call window does).

No doubt the Data/Object window will prove to be an invaluable tool for tracking the value of variables and objects in your Java programs.

The Call Window

The Call window is designed to show a list of function calls made by the program. The items in the Call window are listed in order, the bottom item being the most recent and the top item being the first call made by the program. Figure 14.16 shows the Call window expanded to display all of its contents.

Figure 14.16 : The Cell window for project ManyWindows.

Just like almost everything else in the Symantec Café, the Call window is right-clickable. And there is more than one way to carry out the same action. To keep things simple, however, the following list explains what each command does in the popup menu that appears when you right-click any item in the Call window:

As your programs become more complex, you'll find the Call window very useful for informing you as to exactly when your program is making calls and where those calls are being made to.

The Thread View Window

The Thread View window should be nothing new to you because it was introduced on Day 11 when you were working with animations and threads. The important thing to note right now, however, is that by looking at the Thread View window for this project, you can see that even though you have not created any threads in the project ManyWindows, several threads are at work. This example has unwittingly exemplified the fact that Java is multithreaded from the inside out (see Figure 14.17).

Figure 14.17 : The Thread view window for projects ManyWindows.

At this point, you can continue to execute the project ManyWindows, even though it is in a debugging mode, by clicking the item Debug | Go until End. The project will execute just as it would normally. On the other hand, you can close the debugging mode by terminating the program or by clicking the menu item Debug | Stop Debugging.

What To Do in Symantec Café When You Need Help

This small section is designed to ensure that you are aware of the Help in Symantec Café and what it does. I also included it to expose you to a couple of the ways to access Help in Symantec Café. Inevitably, Help is one of the most important (and most overlooked) features of an integrated development environment. It is a pretty safe bet to say, however, that Symantec Café has done a good job in this area.

The Café Tutorial

Just in case you were not aware, Symantec Café does come with a tutorial. The Café Tutorial is a 41-page introduction to the Symantec Café environment. If you are new to (or still uncomfortable with) some of the material presented in the past two weeks, you'll definitely find it worth your time to go through the tutorial, shown in Figure 14.18.

Figure 14.18 : The Symantec Café Tutorial.

You can invoke the Café Tutorial by clicking Help | Café | Symantec Café Tutorial.

The Symantec Café Help Files

Symantec Café has structured its other Help files into several categories. They can all be called from the Help menu on the main menu bar.

Intro to Java Programming

The Intro to Java Programming Help file, shown in Figure 14.19, is mostly designed to be a tutorial giving you very basic information based purely on the Java programming language through the use of code samples. Many of the topics discussed require a certain level of understanding in Java.

Figure 14.19 : Intro to Java Programming.

The Java API Reference

The Java API Reference, shown in Figure 14.20, is an indispensable tool for Java programmers of all levels. It enables you to access information on all the built-in classes currently available for Java. Not only does it give you the constructors for all of these classes, but it also gives you the definition of what each class, method, and constant variable does. The Java API Reference is designed like a Help file, so you'll also find links to related topics and definitions for various items in each Help item.

Figure 14.20 : The Java Reference.

The Java Language Specification

The Java Language Specification, shown in Figure 14.21, does just about everything the Java API Reference doesn't do. Namely, the Java Language Specification implements various common Java programming methods, as well as built-in classes. This is also an indispensable tool because it is a "how to" Help file, which is something that is usually not well documented in integrated development environments.

Figure 14.21 : The Java Language Specification.

Summary

Congratulations-by ending today's work, you have completed the first two weeks in this book. Today, you learned about using pretty much the remainder of tools available to you in the Symantec Café, things such as how to handle errors, debug Java programs, and use the various debugging tool windows to help you be a more productive Java programmer.

By coming to this point, you have hit a major breaking point in the book. Next week, the topics will become more advance and focused, and less related to each other. But that is not to say that you are not ready for the challenge, because in these two weeks you have learned a lot about Java and Symantec Café.

Q&A

Q
What is the best way to work with errors more intelligently in Java and Symantec Café?
A
Probably the best way to understand error messages more effectively is through good old-fashioned experience. Although many books and reference materials that can help you understand errors more effectively are no doubt available, the best way to be a more intelligent Java debugger is to do more debugging.
Q
What are some common errors that new programmers to Java should look out for?
A
The following list of actions reveals the most common mistakes programmers make that result in compilation errors. In fact, it would be a good idea for you to copy this list and put it by your monitor. That way, the next time you get an error from the compiler, you can run through the list before trying to find more complex solutions.
  • Make sure that the brackets are all balanced, with the number of opening brackets equaling the number of closing brackets. Also, make sure that the brackets are in their proper places. The Source Window Text Editor in Symantec Café helps with this task by placing the brackets automatically in their proper places. The Source Window Text Editor also recognizes unbalanced brackets and reports the problem through the status bar at the bottom of the window.
  • This is a semicolon language. Make sure that you did not blindly put semicolons after everything, but that you instead put them everywhere that they were placed in the Listings.
  • If you haven't already noticed, Java is a real programming language, which means that Java is a case-sensitive programming language. Watch for errors in case.
Q
No matter what I do, I cannot start the debugger. Or when I attempt to start it, the Output window gives me errors, and then Symantec Café tells me it cannot start the debugger. What's the problem?
A
This is most definitely a TCP/IP issue. As mentioned earlier, the Java debugger, which is also used in Symantec Café, requires a TCP/IP stack to run. You can either give it one or pretend to give it one. Go to your Café documentation for more information. You also might want to upgrade to Café version 1.2, which doesn't require a TCP/IP stack for local sessions.