Back to ICS211

Mobius strip

Reading Java Compiler and Runtime Errors

An important part of programming is debugging. Indeed, most programmers spend more time tracking down and eliminating bugs in their code than they spend writing the code itself. One of the most helpful debugging tools is error messages. Though they may be hard to read at first, error messages are actually intended to help you fix the problem. This page will give you a little practice reading compiler and runtime error messages.

Compiler Error Messages

If the compiler knew for certain what was wrong with your code, it would probably fix it for you. And if the compiler knew that much, it wouldn't need you--the programmer--to write the program in the first place! As it is, the compiler simply reports what it found so you can fix it.

Compiler messages have the following format:

[source code filename]:[line number]:[the problem encountered]
[breakdown of problem (sometimes)]
[the line of source code with a caret ^ near the problem]

Let's take a look at a few examples. This one is pretty easy:

Hello.java:6: ';' expected
    System.out.println("Hello, World")
                                      ^

We can see that the problem is on line 6 of Hello.java. The compiler is guessing that there should be a ; where the ^ is pointing. And that is exactly what is wrong.


Hello.java:9: 'class' or 'interface' expected
}
^

This one is a little trickier. This is actually an extra }. Because the class definition had been properly completed, the compiler was expecting only another class or interface definition--not this odd extra character.

Sometimes things like missing or extra braces will cause a whole lot of compiler errors. Advice: start with the first compiler error listed, because sometimes that will fix a number of later errors too.

Also, the compiler can't always exactly figure out where the problem is. It is making a best guess. If the line given is okay, look at previous lines for syntax errors.


Hello.java:7: cannot resolve symbol
symbol  : variable head  
location: class java.lang.Object
    DLLNode curr = o.head;
                    ^

So on line 7 of Hello.java, the compiler couldn't resolve a symbol. (A symbol is something like a class name, a variable, or a method name.) In this case, it says what the symbol is: the variable head. And, because o is an Object, it is looking for this variable head in java.lang.Object. In this case, the problem is probably that we forgot to cast o to a DLList, which would contain a head variable.


DLLTest.java:86: cannot resolve symbol
symbol  : method toArray (java.lang.Object)
location: class DLList
arrStr = list.toArray((Object)arrStr);
                              ^

This is a very similar problem to the previous one. This time it is a method the compiler can't find. And that's because we have a method toArray(Object[]) but we do not have a method toArray(Object).


Hello.java:7: cannot resolve symbol
symbol  : variable size  
location: class DLList
    int curr = o.size;
                ^

Note that this error message is practically the same as the previous two errors. However, this time the problem is a little different. Though the compiler is assuming size is a variable (and so can't find it), it is actually a method: size(). The solution this time is to add the parentheses.


DLLTest.java:87: incompatible types
found   : java.lang.Object[]
required: java.lang.String[]
arrStr = list.toArray(arrStr);
                      ^

This one is a little tricky because of where the caret is placed. It turns out what it is complaining about is that list.toArray(arrStr) evaluates to (or returns) an Object[]. So it found an Object[], but required a String[], because arrStr is a String[]. What is missing here is a cast to String[] before assigning to arrStr

Hopefully this page has shown you that compiler error messages can be useful debugging tools. Sometimes they can be very cryptic and confusing. But keep in mind that the compiler is doing its best to tell you how it is interpreting your code--what it found so far, what it is expecting next, etc. When you can see your code the same way the Java compiler does, you will find your bug.

Runtime Exceptions

Once you have managed to compile your code, it doesn't mean your debugging is done. Runtime errors are much harder to track down, because it means something is wrong with the logic of your program, and not just with the syntax.

Many runtime errors won't crash your program. Instead, you simply get incorrect results because your algorithm is wrong.

Other times you will get a runtime exception that crashes your program. Runtime exceptions also mean that you have a problem with your algorithm. The way to solve runtime exceptions is usually not to catch them, but to fix your algorithm so they don't happen in the first place.

Here is an example of a runtime exception crashing a program [the first line has been wrapped to better fit on the page]:

Exception in thread "main" 
java.lang.ArrayIndexOutOfBoundsException
        at Hello.bar(Hello.java:17)
        at Hello.foo(Hello.java:12)
        at Hello.main(Hello.java:8)

Note that this is actually a print out of the runtime stack. In main(), on line 8 of Hello.java, I called foo(). In foo(), on line 12, I called bar(). And in bar(), on line 17, I generated an ArrayIndexOutOfBoundsException. Though this tells me the line where the problem occurs, I may need to hunt around a bit to find out what's gone wrong.

The most helpful tool when tracking down runtime errors is print statements. Whenever some variable does not contain the value you think it is, put a debug System.out.println() statement in your code to print out the value of that variable. Perhaps your loop is looping once too many times; if you print out the loop counter i, maybe you'll find out if that's the case.

Once you've tracked down the bug, remember to remove your println statements.

Good luck with your debugging!

Further Resources



~ztomasze Index : TA Details: ICS211: Compiler Errors
http://www2.hawaii.edu/~ztomasze
Last Edited: 14 Oct 2004
©2004 by Z. Tomaszewski.