Why FastJSON Lost the amount Field After JDK 11 Upgrade – A Deep Dive

After upgrading to JDK 11, a FastJSON serialization bug caused the amount field in Money objects to disappear, leading to failed refunds; this article details the investigation, from classloader quirks and ASM handling to dependency conflicts and the ultimate fix of removing a problematic jar.

Alibaba Cloud Developer
Alibaba Cloud Developer
Alibaba Cloud Developer
Why FastJSON Lost the amount Field After JDK 11 Upgrade – A Deep Dive

Background

After upgrading the service to JDK 11, class loading order changed, causing different classes to be loaded from multiple JARs, which affected FastJSON serialization results.

Symptoms

Customer reports that the order page cannot initiate a dispute and errors occur.

Resolution Process

Rollback deployed version in two batches of 30 machines, restored service within 6 minutes.

Investigation Steps

Checked JVM parameters, occupied ports, sandbox‑agent plugin, Spring Boot version, and FastJSON configuration.

new SpringApplicationBuilder(DestinyApplication.class)
    .web(WebApplicationType.NONE) // specify non‑web application
    .profiles(DiamondProfiles.load())
    .run(args);

The line .web(WebApplicationType.NONE) interfered with port handling.

@Controller
public static class OkController {
    @ResponseBody
    @RequestMapping("/ok.jsp")
    public String ok() { return "success"; }

    @GetMapping("/checkpreload.htm")
    public @ResponseBody String checkPreload() { return "success"; }
}

Added a configuration to exclude health‑check paths:

icbusession.authorization.exclude-paths=/favicon.ico,/checkpreload.htm,/status.taobao,/ok.jsp

FastJSON Analysis

The issue was traced to FastJSON deserialization of the Money class where the derived amount field was lost on the production machine.

public class Money implements Serializable, Comparable {
    private long cent;
    private Currency currency;
    private String currencyCode;
    public BigDecimal getAmount() {
        return BigDecimal.valueOf(cent, currency.getDefaultFractionDigits());
    }
    public void setAmount(BigDecimal amount) {
        if (amount != null) {
            cent = rounding(amount.movePointRight(2), BigDecimal.ROUND_HALF_EVEN);
        }
    }
}

FastJSON reads getter/setter methods; the production JAR lacked the setAmount method because a custom jar overwrote the class, causing the amount to be zero.

Final Fix

Removed the conflicting custom jar from the dependency tree, which restored proper deserialization of the amount field.

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.

DebuggingJavaserializationclassloaderJDK11
Alibaba Cloud Developer
Written by

Alibaba Cloud Developer

Alibaba's official tech channel, featuring all of its technology innovations.

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.