Introduction
Stack trace shows the sequence of method calls that led to an exception. Essential for debugging.
What is Stack Trace?
Stack trace = list of method calls from the point where exception occurred back to the beginning.
Shows:
- Exception type
- Error message
- Method call sequence
- Line numbers
- File names
Simple Example
public class Main {
static void method3() {
int result = 10 / 0; // Exception here
}
static void method2() {
method3();
}
static void method1() {
method2();
}
public static void main(String[] args) {
method1();
}
}
Stack Trace Output:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.method3(Main.java:3)
at Main.method2(Main.java:7)
at Main.method1(Main.java:11)
at Main.main(Main.java:15)
Reading Stack Trace
java.lang.ArithmeticException: / by zero
at ClassName.methodName(FileName.java:lineNumber)
Parts:
- Exception type: ArithmeticException
- Message: / by zero
- Location: ClassName.methodName
- File: FileName.java
- Line: lineNumber
Stack Trace Direction
Read from top to bottom:
- Top = where exception occurred (most recent)
- Bottom = where program started (oldest)
Exception in thread "main" java.lang.NullPointerException
at MyClass.method3(MyClass.java:15) ← Exception here!
at MyClass.method2(MyClass.java:11) ← Called by method2
at MyClass.method1(MyClass.java:7) ← Called by method1
at MyClass.main(MyClass.java:3) ← Started from main
printStackTrace() Method
public class Main {
public static void main(String[] args) {
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
// Print stack trace
e.printStackTrace();
}
System.out.println("Program continues");
}
}
Getting Stack Trace Elements
public class Main {
public static void main(String[] args) {
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
// Get stack trace as array
StackTraceElement[] elements = e.getStackTrace();
for (StackTraceElement element : elements) {
System.out.println("Class: " + element.getClassName());
System.out.println("Method: " + element.getMethodName());
System.out.println("Line: " + element.getLineNumber());
System.out.println("File: " + element.getFileName());
System.out.println();
}
}
}
}
Nested Method Calls
class Calculator {
int divide(int a, int b) {
return a / b; // Line 3
}
}
class MathService {
Calculator calc = new Calculator();
int calculate(int x, int y) {
return calc.divide(x, y); // Line 10
}
}
public class Main {
public static void main(String[] args) {
MathService service = new MathService();
service.calculate(10, 0); // Line 17
}
}
Stack Trace:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Calculator.divide(Calculator.java:3)
at MathService.calculate(MathService.java:10)
at Main.main(Main.java:17)
Common Stack Traces
NullPointerException:
java.lang.NullPointerException
at MyClass.processString(MyClass.java:25)
at MyClass.main(MyClass.java:10)
Analysis: Line 25 in processString method has null reference.
ArrayIndexOutOfBoundsException:
java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 3
at MyClass.printArray(MyClass.java:15)
at MyClass.main(MyClass.java:7)
Analysis: Line 15 accessing array with invalid index 5.
NumberFormatException:
java.lang.NumberFormatException: For input string: "abc"
at Integer.parseInt(Integer.java:652)
at MyClass.convertNumber(MyClass.java:20)
at MyClass.main(MyClass.java:8)
Analysis: Line 20 trying to convert “abc” to integer.
Analyzing Complete Example
class Student {
String name;
void setName(String name) {
this.name = name.toUpperCase(); // Line 5
}
}
class StudentService {
void processStudent(Student student, String name) {
student.setName(name); // Line 11
}
}
public class Main {
public static void main(String[] args) {
Student student = new Student();
StudentService service = new StudentService();
service.processStudent(student, null); // Line 18
}
}
Stack Trace:
Exception in thread "main" java.lang.NullPointerException
at Student.setName(Student.java:5)
at StudentService.processStudent(StudentService.java:11)
at Main.main(Main.java:18)
Analysis:
- Exception at Student.setName line 5
- Called from StudentService.processStudent line 11
- Called from Main.main line 18
- Problem: null passed to setName, calling toUpperCase() on null
Caused By
Shows original cause of exception.
import java.io.*;
public class Main {
static void readFile() throws IOException {
FileReader fr = new FileReader("nonexistent.txt");
}
public static void main(String[] args) {
try {
readFile();
} catch (IOException e) {
throw new RuntimeException("Failed to read file", e);
}
}
}
Stack Trace:
Exception in thread "main" java.lang.RuntimeException: Failed to read file
at Main.main(Main.java:11)
Caused by: java.io.FileNotFoundException: nonexistent.txt
at FileReader.<init>(FileReader.java:72)
at Main.readFile(Main.java:5)
at Main.main(Main.java:10)
Logging Stack Trace
import java.io.*;
public class Main {
public static void main(String[] args) {
try {
int result = 10 / 0;
} catch (Exception e) {
// Log to console
System.err.println("Error occurred:");
e.printStackTrace();
// Or log to file
try (PrintWriter pw = new PrintWriter("error.log")) {
e.printStackTrace(pw);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
Stack Trace in Multi-threaded
public class Main {
public static void main(String[] args) {
Thread t = new Thread(() -> {
int result = 10 / 0;
});
t.start();
}
}
Stack Trace:
Exception in thread "Thread-0" java.lang.ArithmeticException: / by zero
at Main.lambda$main$0(Main.java:4)
at java.lang.Thread.run(Thread.java:748)
Note: Shows thread name “Thread-0”.
Practical Debugging
Step 1: Find Exception Type
java.lang.NullPointerException
Means: Using null reference
Step 2: Read Message
Cannot invoke "String.length()" because "str" is null
Means: Variable str is null
Step 3: Find Location
at MyClass.method(MyClass.java:25)
Means: Error at line 25 in method
Step 4: Check Call Chain
at MyClass.method(MyClass.java:25)
at MyClass.process(MyClass.java:15)
at MyClass.main(MyClass.java:7)
Trace: main → process → method
Common Patterns
Pattern 1: Null Pointer
java.lang.NullPointerException
Fix: Check for null before use
Pattern 2: Array Index
java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds
Fix: Check array length
Pattern 3: Number Format
java.lang.NumberFormatException: For input string
Fix: Validate string before parsing
Pattern 4: File Not Found
java.io.FileNotFoundException
Fix: Check file exists
Best Practices
- Read from top - exception location
- Check line numbers - exact problem spot
- Follow call chain - understand flow
- Look for “Caused by” - root cause
- Log stack traces - for debugging
- Don’t ignore - always investigate
- Fix root cause - not symptoms
Quick Reference
// Print stack trace
try {
// code
} catch (Exception e) {
e.printStackTrace(); // To console
}
// Get stack trace elements
StackTraceElement[] elements = e.getStackTrace();
for (StackTraceElement element : elements) {
System.out.println(element.getClassName());
System.out.println(element.getMethodName());
System.out.println(element.getLineNumber());
}
// Exception info
e.getMessage() // Error message
e.toString() // Exception type + message
e.getCause() // Original exception
Exam Tips
Remember:
- Stack trace shows method call sequence
- Top = where exception occurred
- Bottom = where program started
- printStackTrace() prints trace
- Line numbers show exact location
- Caused by shows root cause
- Thread name in multi-threaded
- StackTraceElement for details
- Read top-down for debugging
- Essential for debugging
Common Questions:
- What is stack trace?
- How to read stack trace?
- Direction of stack trace?
- printStackTrace() method?
- Getting stack trace elements?
- What is “Caused by”?
- Stack trace in multi-threading?
- How to debug using stack trace?
- Common patterns?
- Best practices?