How to Uncover Hidden NoClassDefFoundError in Dubbo Using Arthas

This article walks through a real‑world Dubbo debugging case where a NoClassDefFoundError was silently swallowed, showing how to use Arthas watch commands to capture the exception, analyze the root cause in static initializers, and fix the logging dependency conflict.

Java Backend Technology
Java Backend Technology
Java Backend Technology
How to Uncover Hidden NoClassDefFoundError in Dubbo Using Arthas

Background

In a three‑service call chain (A → B → C), a recent change in service C2 introduced log sanitization and upgraded the logging framework from Log4j to Logback. After redeploying, service B returned an error "Channel C2 not found" while C2 still processed the request.

Root Cause Investigation

The error was hidden because B caught the exception without logging it. Using

Arthas
watch

on the doPay method revealed a NoClassDefFoundError caused by the missing org.apache.log4j.Logger class referenced in a static initializer of GELogger.

public Response pay(Request req) {
    try {
        if (!isSupport(req.getChnlCode())) {
            return new Response("ERROR", "未找到相关渠道应用");
        }
        return doPay(req);
    } catch (Exception e) {
        return new Response("ERROR", "未找到相关渠道应用");
    }
}

The static block in GELogger attempted to create a Log4j logger, which failed after Log4j was excluded, triggering the class‑loading error.

private static Logger logger;
static {
    System.out.println("static init");
    logger = Logger.getLogger(NoClassDefFoundErrorTestService.class);
    System.out.println("Logger init success");
}

Arthas Debugging Steps

Run the following command to watch method parameters and thrown exceptions:

watch com.dubbo.example.DemoService doPay -e -x 2 '{params,throwExp}'

This command captures the exception after doPay throws, confirming the NoClassDefFoundError.

Resolution

Remove the GELogger dependency (or replace Log4j with SLF4J) so the static initializer no longer references the missing class. After exclusion, the service starts without errors.

Dubbo Internal Exception Handling

Dubbo’s provider filter executes the business method first; the subsequent static‑initializer error occurs after the business logic succeeds. The exception propagates through HeaderExchangeHandler#handleRequest, becomes a RemotingException on the consumer side, and is finally wrapped as an RpcException returned to the caller.

Key Takeaways

Always log stack traces when catching exceptions.

Missing runtime classes cause NoClassDefFoundError and halt class initialization.

Avoid hard‑coding specific logging frameworks in shared libraries; prefer SLF4J.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

debuggingjavaDubboNoClassDefFoundError
Java Backend Technology
Written by

Java Backend Technology

Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.