How to Instantly Trace Java Method Call Stacks for Faster Debugging

This article explains how to build and use a Java StackTrace utility that extracts and filters method call chains, enabling developers to quickly locate error sources, streamline debugging, and improve operational efficiency by visualizing execution paths through customizable parameters and integration examples.

JD Cloud Developers
JD Cloud Developers
JD Cloud Developers
How to Instantly Trace Java Method Call Stacks for Faster Debugging

Introduction

This article starts from the pain points of daily on‑call issue investigation, analyzes the call‑chain reuse and business context, and presents a chain‑tracking tool built with stack frames to display a request's serial method calls, helping quickly locate code origins and traffic entry points, thereby improving debugging efficiency.

Current Situation Analysis

During on‑call duty, developers often receive screenshots of error messages and need as much information as possible to analyze the scenario.

Below is a typical error screenshot.

From the screenshot we can initially obtain:

Menu name: "Change Order Off‑Shelf" – the operation that triggered the error.

Error message: "Serial number status is off‑stock, please check."

Other auxiliary info: user‑scanned or entered code starting with 86, SKU, product name, location, etc.

Common troubleshooting steps:

Check the user‑entered 86 code against the serial number data to see if it exists and is truly off‑stock.

If the 86 code is a serial number and is off‑stock, the case can be closed quickly.

If the code is not a serial number or not off‑stock, locate the source of the error message in the code by searching the codebase or logs.

Search the codebase for the error message text or retrieve it from logs (requires the message to be printed with appropriate log level).

If the same message appears in multiple places, further identify which occurrence is relevant to the current error.

In complex systems, method reuse is common; different contexts and parameters lead to different business logic paths.

The core pain point: how to quickly locate the code source based on limited hint information.

Inspiration

The idea comes from Java's exception mechanism. While exception stacks are useful for locating problems, they can also be overwhelming.

Four types of information are present in a stack trace:

Fully qualified class name

Method name

File name

Line number

These allow precise location of code origins, and the order reflects the sequence of execution (first scene, second scene, etc.).

This is similar to JVM method stack frames: each method call creates a new stack frame containing local variables, operand stack, constant pool references, etc.

Approach

From java.lang.Throwable we can obtain the StackTraceElement[], which contains the same information shown in exception stacks.

Tool Development

The core code is simple: StackTraceElement is provided by the JDK, and the tool filters necessary information and formats it into an ordered chain for easy visual inspection.

Parameters

pretty : only concatenate class and method names (no file name or line number). Non‑pretty includes all four parts.

simple : filters out proxy‑enhanced methods that appear in our code.

specifiedPrefix : keep stack information for specified package prefixes, removing excessive middleware details.

Additional filters for common proxy artifacts:

FastClassBySpringCGLIB

EnhancerBySpringCGLIB

lambda$

Aspect

Interceptor

Convenient wrapper methods are also provided.

Usage Examples

1. Call chain without filtering middleware or proxy methods:

Thread#run => ThreadPoolExecutor$Worker#run => ThreadPoolExecutor#runWorker => BaseTask#run => JSFTask#doRun => ProviderProxyInvoker#invoke => FilterChain#invoke => SystemTimeCheckFilter#invoke => ProviderExceptionFilter#invoke => ProviderContextFilter#invoke => InstMethodsInter#intercept => ProviderContextFilter$eone$auxiliary$9f9kd21#call => ProviderContextFilter#eone$original$invoke$p882ot3$accessor$eone$pclcbe2 => ProviderContextFilter#eone$original$invoke$p882ot3 => ProviderGenericFilter#invoke => ProviderUnitValidationFilter#invoke => ProviderHttpGWFilter#invoke => ProviderInvokeLimitFilter#invoke => ProviderMethodCheckFilter#invoke => ProviderTimeoutFilter#invoke => ValidationFilter#invoke => ProviderConcurrentsFilter#invoke => ProviderSecurityFilter#invoke => WmsRpcExceptionFilter#invoke => ... (continues)

2. Call chain after specifying package prefix filtering:

LockAspect#lock => StockTransferAppServiceImpl#increaseStock => MonitorAspect#monitor => StockRetryExecutor#operateStock => ...

3. Call chain after removing Spring proxy methods:

LogAspect#log => LockAspect#lock => ValidationAspect#validate => ProviderContextFilter#eone$original$invoke => StockTransferAppServiceImpl#decreaseStock => ...

4. Call chain after removing custom proxies:

StockTransferAppServiceImpl#increaseStock => StockTransferServiceImpl#increaseStock => BaseStockOperation#go => DataBaseExecutor#operate => StockRetryExecutor#operateStock => StockRepositoryImpl#operateStock

5. Call chain with file names and line numbers:

StockTransferAppServiceImpl#increaseStock(StockTransferAppServiceImpl.java:103) => StockTransferServiceImpl#increaseStock(StockTransferServiceImpl.java:168) => BaseStockOperation#go(BaseStockOperation.java:152) => DataBaseExecutor#operate(DataBaseExecutor.java:34) => ...

Online Application Practice

After integrating the stack‑trace tool, error hint words can be used to retrieve corresponding logs and quickly locate the entry point code, e.g., from ImmediateTransferController#offShelf through a chain of proxies to the business method.

Applicable Scenarios

Output stack trace to logs when business exceptions occur.

Include call‑stack information in monitoring alerts.

Print call chains in complex method‑reuse scenarios for analysis.

Other similar use cases.

Extension

The tool was later integrated into a SQL‑coloring MyBatis plugin to add method‑call information to SQL logs.

Upgrade steps:

Upgrade sword-mybatis-plugins to version 1.0.6‑SNAPSHOT.

Add the stack‑trace utility dependency.

<dependency>
    <groupId>com.jd.sword</groupId>
    <artifactId>sword-utils-common</artifactId>
    <version>1.0.0‑SNAPSHOT</version>
</dependency>

Configure MyBatis plugin:

<plugin interceptor="com.jd.sword.mybatis.plugin.sql.SQLMarkingInterceptor">
    <property name="enabled" value="true"/>
    <property name="stackTraceEnabled" value="true"/>
    <property name="specifiedStackTracePackages" value="com.jdwl.wms.stock"/>
    <property name="stackTraceSamplingRate" value="1/2"/>
</plugin>

How to Integrate This Tool?

Add the Maven dependency shown above, then use the static methods provided by StackTraceUtils:

com.jd.sword.utils.common.runtime.StackTraceUtils#simpleTrace()
com.jd.sword.utils.common.runtime.StackTraceUtils#simpleTrace(String...)
com.jd.sword.utils.common.runtime.StackTraceUtils#trace()
com.jd.sword.utils.common.runtime.StackTraceUtils#trace(String...)
com.jd.sword.utils.common.runtime.StackTraceUtils#trace(boolean)
com.jd.sword.utils.common.runtime.StackTraceUtils#trace(boolean, boolean, String...)
DebuggingJavabackend developmentPerformance MonitoringStackTraceTooling
JD Cloud Developers
Written by

JD Cloud Developers

JD Cloud Developers (Developer of JD Technology) is a JD Technology Group platform offering technical sharing and communication for AI, cloud computing, IoT and related developers. It publishes JD product technical information, industry content, and tech event news. Embrace technology and partner with developers to envision the future.

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.