Back to Class Loading & Compilation
Q2Question 2 of 4

What is the class-loader delegation model?

Key Concepts
  • Parent-first delegation: each class loader asks its parent before trying to load a class itself
  • Application → Platform → Bootstrap: the chain goes up before trying locally
  • This prevents duplicate loading: java.lang.String is always loaded by Bootstrap, never by your code
  • If no parent can load the class, the originating class loader tries, then throws ClassNotFoundException
  • This model ensures security: you cannot create a fake java.lang.String in your classpath

Definition

Each class loader delegates to its parent first. Only if the parent cannot find the class does the child try. This prevents duplicate loading and ensures core classes always come from Bootstrap.

Delegation model:

  • Request goes up: Application → Platform → Bootstrap.
  • Bootstrap tries first. If it has the class (java.lang.String), it loads it. Done.
  • If not found, Platform tries. If it has the class, it loads it.
  • If not found, Application tries. Looks in the classpath.
  • If nobody has it: ClassNotFoundException.

A bank branch (Application) receives a request for a form. Before printing its own, it asks the regional office (Platform). The regional office asks the head office (Bootstrap). If the head office has it, everyone uses that version. Only if nobody has it does the branch look in its own files.

Understanding the Concepts

How delegation works

DIAGRAM
Account.class requested by Application ClassLoader
  │
  ▼ delegate to Platform
  │ Platform does not have Account
  ▼ delegate to Bootstrap
  │ Bootstrap does not have Account
  ▼ back to Platform: cannot load
  ▼ back to Application: looks in classpath
  │ found in target/classes/ → loads Account.class
  ▼ done

java.lang.String requested by Application ClassLoader
  │
  ▼ delegate to Platform
  ▼ delegate to Bootstrap
  │ Bootstrap has java.lang.String → loads it
  ▼ done (Application never tries)

Why is this important for security?

If you create a java.lang.String class in your classpath, the delegation model ensures Bootstrap's real String is always loaded instead. You cannot replace core JDK classes.

JAVA
// Even if you put this in your classpath:
package java.lang;
public class String { ... }  // this is NEVER loaded – Bootstrap's String wins

What about ClassNotFoundException vs NoClassDefFoundError?

  • ClassNotFoundException: The class loader searched all its sources and could not find the .class file. Usually a missing dependency.
  • NoClassDefFoundError: The class was found once but its initialization failed (e.g., static block threw). The class is permanently broken.

What should a senior engineer know?

  • Tomcat uses child-first (inverted) delegation for webapp classes, so each webapp can have its own version of a library.
  • OSGi uses peer-to-peer class loading instead of strict parent delegation.
  • Java modules (Java 9+) add another layer of control via module-info.java exports/requires.

What are common mistakes?

A common mistake is not understanding the concept fully before using it in production banking applications.

Wrong approach:

JAVA
package com.bank.service;

public class TransferService {
    public void transfer(String fromAccount, String toAccount, double amount) {
        // WRONG: using double for money
        double balance = getBalance(fromAccount);
        balance = balance - amount;
    }
    private double getBalance(String id) { return 10000.0; }
}

Correct approach:

JAVA
package com.bank.service;

import java.math.BigDecimal;

public class TransferService {
    public void transfer(String fromAccount, String toAccount, BigDecimal amount) {
        // CORRECT: using BigDecimal for money
        BigDecimal balance = getBalance(fromAccount);
        balance = balance.subtract(amount);
    }
    private BigDecimal getBalance(String id) { return new BigDecimal("10000.00"); }
}

Always use BigDecimal for monetary calculations in banking systems to avoid floating-point precision errors.

What are the edge cases?

Edge cases can cause unexpected behavior in banking applications. Here are some to watch for.

JAVA
package com.bank.edge;

public class EdgeCaseDemo {
    public static void main(String[] args) {
        // Edge case 1: null handling
        String accountId = null;
        try {
            System.out.println(accountId.length());
        } catch (NullPointerException e) {
            System.out.println("Null account ID");
        }

        // Edge case 2: empty vs null
        String emptyId = "";
        System.out.println(emptyId.isEmpty());  // true
        System.out.println(emptyId == null);     // false

        // Edge case 3: boundary values
        java.math.BigDecimal zero = java.math.BigDecimal.ZERO;
        java.math.BigDecimal negativeBalance = new java.math.BigDecimal("-0.01");
        System.out.println(zero.compareTo(negativeBalance) > 0);  // true
    }
}
TEXT
Null account ID
true
false
true

Always test with null values, empty strings, boundary values, and negative amounts in banking applications.

What are common interview follow-up questions?

Interviewers often follow up with these related questions:

  • How does this concept apply to a high-throughput banking transaction system?
  • What are the performance implications in a production environment?
  • How would you debug issues related to this concept?
  • What tools would you use to monitor this in production?
  • How does this behave differently in Java 8 vs Java 17+?

When answering follow-up questions, always relate your answer back to practical experience. For example, at National Bank of India, Rajesh debugged a production issue related to this concept by using JFR recordings and heap dumps. Providing concrete examples from banking systems shows the interviewer that you understand both the theory and the practice.

Visual Overview

DIAGRAM
  Delegation chain (parent-first):

  Application CL → requests Account.class
    ↑ delegate to
  Platform CL → does not have Account
    ↑ delegate to
  Bootstrap CL → does not have Account
    ↓ return: not found
  Platform CL → not found
    ↓ return: not found
  Application CL → searches classpath → found → loads

  Security: you CANNOT replace java.lang.String
  because Bootstrap always loads it first.

Key Takeaway

The class-loader delegation model means each loader asks its parent before trying itself. This ensures core classes always come from Bootstrap, prevents duplicate loading, and blocks malicious replacements of JDK classes.

One sentence to remember: parent-first delegation means Bootstrap loads core classes, Platform loads extensions, and Application loads your code – in that order, always.

---

Share
Use ← → arrow keys to navigate