You build Java debugging skills by following one repeatable loop: reproduce the failure, read the stack trace, isolate the cause, fix it, and confirm the fix with a test. Practise that loop on small, realistic enterprise bugs before the internship starts, and keep a written log while it runs. This guide gives you the flowchart, five buggy snippets to practise on, a worked example and a 14-day plan.
The Java debugging flowchart: reproduce, read, isolate, fix, confirm
Most beginners jump straight to editing code. Interns who impress mentors do the opposite: they slow down at the start and prove the fix at the end. The flowchart below is the whole playbook on one screen.
[1. REPRODUCE]
Can you trigger the failure on demand?
|-- No --> collect input, logs, environment, time; try again
|-- Yes --> write down exact steps + input
|
v
[2. READ THE STACK TRACE]
Find the exception type, message, and the first
line of YOUR code (not framework code)
|
v
[3. ISOLATE]
Shrink to the smallest failing case
(unit test, main method, or breakpoint)
|-- Cause still unclear? --> form a hypothesis,
| test it with one change, repeat
|
v
[4. FIX]
Change ONE thing that addresses the cause, not the symptom
|
v
[5. CONFIRM]
Failing test now passes? Other tests still pass?
|-- No --> revert, return to step 3
|-- Yes --> commit with a note, add test, write log entry
Step 1: Reproducing the bug before touching code
A bug you cannot reproduce is a bug you cannot prove you fixed. Before changing anything, write down:
- The exact input or request that triggers it (the customer ID, the JSON body, the file).
- The environment: Java version, build tool, database, config profile.
- How often it happens: every time, only for some records, only under load, only after a restart.
- What you expected and what actually happened, in one sentence each.
“Only for some records” is itself a clue. It usually points to null or empty values, boundary data or an unusual format. “Only under load” points to shared state, threads or resource exhaustion.
Free 2-Week CareerSwami Internship
Online, 14 days, with a free offer letter and a free completion certificate once you finish the work. Check with your college that it fits your requirement before you enrol.
Step 2: Reading a Java stack trace from the bottom of the cause chain
A stack trace lists the call chain at the moment of failure, most recent call first. Read it in this order:
- The exception class and message on the first line.
- Any “Caused by:” lines at the bottom. The last one is usually the root cause.
- The first line that mentions your own package. Framework lines above it show how you got there; your line shows what you did.
The table below maps common exceptions in enterprise Java to the first thing worth checking.
| Exception | What it usually means | First check |
|---|---|---|
| NullPointerException | A reference was null when you used it | The exact expression on the failing line; which call in a chain returned null |
| ClassCastException | Wrong runtime type, often from raw collections or deserialisation | What type was actually put in |
| ConcurrentModificationException | A collection was changed while being iterated | Removal inside a for-each loop, or shared lists across threads |
| NumberFormatException | A string was not a valid number | Whitespace, empty strings, locale-specific separators |
| SQLException / timeout waiting for connection | Bad query, or the pool has no free connections | Are connections, statements and result sets always closed? |
| StackOverflowError | Unbounded recursion | Repeating frames in the trace; a missing base case or a toString/equals cycle |
| OutOfMemoryError | Heap exhausted | Collections or caches that only grow |
| NoSuchMethodError / ClassNotFoundException | Dependency version mismatch at runtime | The dependency tree in Maven or Gradle |
Step 3: Isolating the cause with breakpoints and small tests
Isolation means making the problem smaller until only the cause remains. Three tools do most of the work:
- A failing unit test. Write the smallest JUnit test that reproduces the bug. It becomes your proof at step 5.
- A conditional breakpoint. In IntelliJ IDEA or Eclipse, pause only when a condition is true, such as
id == 4021. This is far better than stepping through 500 loop iterations. - Hypothesis, one change, observe. Say “I think the address is null for customers without a billing record”, change or log only that, and see whether the evidence agrees.
Prefer a debugger over scattered System.out.println calls. If you must log, use the project’s logger at an appropriate level and remove noisy temporary lines before committing.
Steps 4 and 5: Fixing the cause and proving the fix
A good fix addresses why the bad state arose, not just where it surfaced. Wrapping a failing line in try/catch and ignoring the exception hides the bug and creates a harder one later. Before committing, run through this checklist:
- Does the previously failing test now pass?
- Does the whole test suite still pass?
- Did you change only what the fix needed?
- Can you explain the root cause in two sentences to a teammate?
- Is there a regression test that would fail if someone reintroduced the bug?
Five buggy Java snippets drawn from typical enterprise code
These are illustrative practice snippets written for this article. They are simplified versions of patterns common in service and data-access layers, and they have not been compiled or run here. Set up a small Maven project, paste each one in, and apply the five steps before reading the hints.
Snippet 1: A customer lookup that fails for some customers
public String customerCity(long id) {
Customer c = customerRepo.findById(id);
return c.getAddress().getCity().toUpperCase();
}
Symptom: NullPointerException, but only for certain customer IDs.
Practice question: There are at least three places a null can come from on that one line. Which are they, and what should the method return for a customer with no address? Consider Optional and an explicit decision about the missing-data case.
Snippet 2: A report that works for hours and then hangs
public List<String> loadNames() throws SQLException {
Connection con = dataSource.getConnection();
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("SELECT name FROM users");
List<String> names = new ArrayList<>();
while (rs.next()) {
names.add(rs.getString(1));
}
return names;
}
Symptom: After many calls, requests time out waiting for a database connection.
Practice question: What is never released? Rewrite it with try-with-resources and explain why the failure appears only after a delay.
Snippet 3: Dates that are occasionally wrong under load
private static final SimpleDateFormat FMT =
new SimpleDateFormat("yyyy-MM-dd");
public Date parse(String s) throws ParseException {
return FMT.parse(s);
}
Symptom: Rare wrong dates or odd parse errors when many requests arrive together; none in single-user testing.
Practice question: Why is one shared formatter unsafe across threads? Compare a fix using java.time.LocalDate and DateTimeFormatter.
Snippet 4: Amounts that “equal” each other but do not
BigDecimal expected = new BigDecimal("10.0");
BigDecimal actual = new BigDecimal("10.00");
if (expected.equals(actual)) {
markPaid();
}
BigDecimal fee = new BigDecimal(0.1);
Symptom: Invoices that match on value are not marked paid, and a fee prints with a long tail of digits.
Practice question: What does BigDecimal.equals compare besides the numeric value? Which method compares value only? Why does constructing from a double behave differently from constructing from a string?
Snippet 5: A transaction that does not roll back
@Service
public class OrderService {
public void placeOrder(Order o) {
save(o);
}
@Transactional
public void save(Order o) {
orderRepo.save(o);
auditService.write(o); // throws on failure
}
}
Symptom: When the audit call fails, the order is still stored.
Practice question: In Spring, transactional behaviour is typically applied through a proxy. What happens when a method calls another method on the same object? Where should the annotation go, or how should the call be restructured?
Worked example: tracing Snippet 1 from symptom to confirmed fix
This walkthrough is illustrative. The trace is a made-up shape, not output from a real run.
java.lang.NullPointerException: Cannot invoke "Address.getCity()"
because the return value of "Customer.getAddress()" is null
at com.example.shop.CustomerService.customerCity(CustomerService.java:14)
at com.example.shop.ReportController.cityReport(ReportController.java:33)
- Reproduce: Calling the method with ID 4021 fails every time; ID 1 works. The condition is “customer 4021 has no address”.
- Read the trace: Modern Java’s helpful NPE message says
getAddress()returned null. The first line in your package isCustomerService.java:14. - Isolate: Write a JUnit test that builds a
Customerwith no address and callscustomerCity. It fails with the same exception. - Fix: Decide the behaviour with the team (for example, return “UNKNOWN”). Then guard each step:
return Optional.ofNullable(customerRepo.findById(id)) .map(Customer::getAddress) .map(Address::getCity) .map(String::toUpperCase) .orElse("UNKNOWN"); - Confirm: The new test passes, the old tests pass, and a second test covers a null city. Log the root cause in one line: “Customers without a billing address have a null address; the method assumed non-null.”
Debugging log template and self-scorecard for each bug you fix
Keep a short log for every bug, in your notes or a shared document. It trains the habit and gives you material for interview answers and the final report.
| Field | What to write | Self-score (0-2) |
|---|---|---|
| Symptom | What was observed, in one sentence | Specific enough that a stranger could repeat it? |
| Reproduction steps | Exact input and environment | Fails every time you follow it? |
| Key trace line | Exception plus the first line in your own code | Correct line identified? |
| Hypotheses tried | What you suspected and how you tested it | One change at a time? |
| Root cause | Why the bad state happened | Cause, not symptom? |
| Fix and test | The change and the test that guards it | Test fails without the fix? |
| Lesson | One pattern to watch for next time | Reusable beyond this bug? |
Score each row 0 (missing), 1 (partial) or 2 (solid). Out of 14, aim for 11 or more by the end of week one.
A 14-day Java debugging practice plan for a two-week internship
If you are doing the free two-week online internship from CareerSwami, which comes with a free offer letter and a free completion certificate after successful completion, the plan below fits its 14-day length. Use it as a personal practice routine alongside your tasks; the internship’s own tasks and schedule come first. It also works as pre-internship preparation if you compress it.
| Days | Focus | Output |
|---|---|---|
| 1-2 | Set up IDE, Maven or Gradle, JUnit. Learn the debugger: breakpoints, step over/into, watches, conditional breakpoints. | One working project where you can pause and inspect variables |
| 3-4 | Stack traces: deliberately cause five exceptions from the table and read each trace aloud. | Five annotated traces |
| 5-6 | Snippets 1 and 2: null handling and resource leaks. | Two log entries plus tests |
| 7 | Review week one; score your logs. | Scorecard and weak-spot list |
| 8-9 | Snippets 3 and 4: thread safety and BigDecimal. | Two log entries plus tests |
| 10-11 | Snippet 5: proxies and transactions. Read your logging output from a small Spring Boot app. | One log entry; a note on how the framework applies annotations |
| 12 | Debug a bug in your own internship task using the full loop. | A real log entry |
| 13 | Write a regression test for every bug you have fixed. | A test class per bug |
| 14 | Summarise: three root causes you now recognise on sight. | A one-page reflection for your report and interviews |
Tezpur University students: fitting Java debugging practice into the 2019 academic regulations
Tezpur University describes itself on its home page as a Central University established by an Act of Parliament in 1994. Its academic rules for UG and PG students are in the Regulations on Academic Matters – 2019, approved by the 36th Academic Council on 27-09-2019 and accepted by the 95th Board of Management on 11-11-2019. These are university-issued regulations; they do not mention affiliated colleges. They are from 2019, so check the current version before relying on any detail.
Two parts matter for debugging practice. First, clause 1.12 provides a break at the end of each semester that students may use for short courses, project work, internships and industrial training, among other activities. That is a natural window for the 14-day plan above. Second, Clause 3.1.3 and Table 3.3 govern Project Courses: a mid-semester examination (presentation, viva, progress report) and an end-semester examination (presentation, viva, dissertation). If you take a Java project, the debugging log doubles as evidence of progress and gives you real material for the viva.
Clause 1.11 says the Controller of Examinations notifies the Academic Calendar each year, covering classes, examinations and semester breaks. Break dates come from that calendar, not from this guide. The university’s Training and Placement Section page splits into an Engineering site and a Non-Engineering site, which are the places to ask about internship processes.
The regulations as read describe internships only as a permitted semester-break activity. Whether a particular internship, online or otherwise, earns credit or must be reported in a specific format is not stated there, so do not assume it. Take these steps:
- Download the current Academic Calendar from the university website or ask your department office for the notified semester-break dates.
- Ask your department office or programme coordinator in writing: “Does an online internship during the semester break need prior approval, and is any document required afterwards?”
- Ask whether the 2019 regulations have been amended or replaced, and request the latest version.
- Open the Engineering or Non-Engineering Training and Placement site that matches your programme and ask what internship documentation they expect.
- Check your programme’s curriculum document for any project or internship course, and ask your supervisor whether Java debugging work could feed into a Project Course.
- Keep copies of any reply you receive by email.
Habits that make Java debugging faster during the internship
- Ask well. When you ask a mentor for help, bring the symptom, reproduction steps, the trace and what you have already tried. Mentors respond better to this than to “it is not working”.
- Read the library source. IDEs let you jump into framework code; seeing why an exception is thrown often answers the question.
- Use version control as a debugger.
git diffandgit bisecthelp find which change introduced a regression. - Take breaks. A fresh look after ten minutes often shows an obvious typo or wrong assumption.
- Never debug on production data. Use test data or masked copies, and follow your team’s data rules.
Frequently Asked Questions
What is the first thing to do when a Java program throws an exception?
Reproduce it with a known input, then read the exception type, message and the first stack trace line in your own code. Do not change anything until you can trigger the failure on demand.
Is System.out.println acceptable for debugging in an internship?
For a quick local check it is fine, but a debugger with breakpoints is usually faster and leaves no clutter. In shared code, use the project’s logging framework and remove temporary output before committing.
How do I debug a bug that only happens sometimes?
Look for what differs between the failing and passing cases: input data, timing, threads or accumulated state. Intermittent failures often involve shared mutable state, as in the SimpleDateFormat snippet, or resources that run out slowly, as in the connection leak snippet.
Which IDE should I use for Java debugging?
IntelliJ IDEA (Community edition) and Eclipse both offer breakpoints, conditional breakpoints and variable inspection. Use whichever your team uses so you can follow their shortcuts and settings.
Do I need to know Spring to practise these snippets?
Snippets 1 to 4 need only core Java and JDBC. Snippet 5 uses Spring annotations; a basic Spring Boot tutorial is enough to follow it, and the underlying idea, that calls on the same object bypass a proxy, is worth learning early.
Can I use my debugging log in a viva or interview?
Yes. Explaining a bug from symptom to root cause to regression test shows structured thinking. Use only real bugs you worked on, and describe them accurately. For a Project Course at Tezpur University, ask your supervisor what progress evidence they expect.
Does the two-week internship give academic credit?
The CareerSwami internship is free, lasts two weeks (14 days) and provides an offer letter and a completion certificate after successful completion. Whether your department grants credit or requires specific paperwork is decided by your university, so ask your department office in writing.
How many bugs should I practise on before an internship starts?
Quality matters more than count. Fixing the five snippets above with a full log entry and a regression test each is a solid base. Add bugs from your own coursework as you go.
Related Java & Enterprise Software guides
- Soban Singh Jeena University: Setting Up Your Java Development Environment Without Surprises
- Bhagwant Global University Students: Learning Hibernate and JPA Through a Small Data Project
- IIIT Bangalore Students: Using a Java Internship to Explore Microservices Without Overreaching
- All Java & Enterprise Software internship guides
Ready to put this into practice?
Join the free two-week CareerSwami online internship in Java & Enterprise Software. The internship, the offer letter and the completion certificate are free.










